2010-07-15 97 views
3

我一直在研究一個應用程序,該應用程序允許構建第三方擴展來擴展應用程序的功能。當然,所有這些都在PHP中。我想通過校驗和功能在特定目錄中運行文件來添加一些安全填充。如果文件未通過校驗和,則文件不被「包含」,通知該安裝的管理員,並且該模塊被禁用,直到管理員採取行動(重新啓用並記錄該異常或重新安裝模塊) 。包含之前的PHP校驗和()

我現在遇到的問題是無論何時用戶運行include()函數都可以運行該校驗和。我寧願不讓他們爲了包含一個文件而背靠背運行兩個函數,但是如果必須的話,我會的。並非所有的第三方擴展都會非常願意運行兩個函數(類似於if(checksum_function($bleh)) include($bleh);),即使它們是,執行include()時運行校驗和會更容易(也更安全),而不是雙倍行數爲include()報表。

我已經做了一些搜索,並沒有找到太多。想法?提前致謝!

回答

0

如果您的includes包括以某個系統命名的類(例如MyPlugin_Text),那麼您可以使用PHP的autoloading。自動加載可用於在首次創建類的對象時自動包含文件。

極其簡單的例子:

function __autoload($class_name) { 

    require_once $class_name . '.php'; 
} 

$myTextPlugin = new MyPlugin_Text(); 

顯然,你會想要擴展自動加載,如僅對從MyPlugin_開始的類進行預加載,並加載來自特定文件夾的預加載。

除了編寫自定義包裝函數之外,我知道沒有其他方法可以實現您想要執行的操作。

我喜歡你的想法。然而,計算校驗和 - 例如使用crc32() - 相對昂貴。不應該有太多,也不會太大,包括這種方式加載。另外,如果攻擊者能夠修改系統中的PHP文件,他們也可以直接執行它們,而不需要您的中央應用程序。此練習的實際安全收益可能很小。

+0

crc碰撞可以使用代數來計算。 – rook 2010-07-15 07:24:07

+0

感謝Pekka。我打算爲我的校驗和使用md5,但我想這會更加昂貴。我沒有想過使用__autoload()。我可能會放棄這個想法,因爲一旦實施其他一切,實際上可能會非常昂貴。不過,我肯定會玩一些__autoload()。謝謝! – Swivel 2010-07-15 07:32:38

+0

@您認爲惡意腳本修復該文件是否意味着它通過了檢查?在大多數情況下,我認爲這不會成爲一種危險,因爲如果攻擊者a)知道安全機制並且b)可以在相關網絡空間上寫入文件,則無論如何都會丟失。不過,好點。 – 2010-07-15 07:33:02

0

考慮寫一個包裝爲include

function include_safe($library) { 
    if(checksum_function($library)) 
     include($library); 
} 

你不會找到許多開發商是「快樂」使用的特點就是這樣,但你也不能重寫PHP語言結構(如includerequire)。具有包裝所有內容的功能方便快捷,因此開發人員可能會使用它。

+0

你的目的是什麼校驗和?你如何去驗證這個校驗和與你想包含的東西有關?那麼我會使用這個函數'make_everything_secure_ever()',然後沒有人會攻擊我。你不想知道這個功能是幹什麼的嗎? @ – rook 2010-07-23 00:18:25

+1

@Rook OP正在尋找解決方案的適當語法,而不是安全實現。事實上,如果你真的要閱讀這個問題,OP甚至提供了「checksum_function」的名字。對我來說更合適的答案是建議OP使用裝飾器,儘管他們很遺憾在PHP中不存在。我可以理解你是痛苦的,但孩子氣地投票下來的答案,並留下公然無知的評論是我稱之爲「不專業」。 – mattbasta 2010-07-23 16:46:59

+0

謝謝mattbasta。 – Swivel 2010-07-27 05:07:50

0

在許多移動代碼平臺中,通常會看到使用RSA Digital Signature簽名的可執行代碼。這允許授權機構「確定」一段可以分發第三方的代碼,並且客戶知道代碼是安全的。數字簽名用於幫助防止現代控制檯視頻遊戲的盜版。它們也用於驗證軟件更新來自供應商,而不是攻擊者。

這個php應用程序可以有公鑰(甚至可以用這個公鑰分發)。管理員可以訪問公鑰和私鑰,使用它可以簽署一個.php文件。在包括簽名可以被檢查。如果php文件被修改或損壞,簽名將不會通過檢查。

在實踐中,PHP應用程序執行很多包含,因此任何驗證功能都將是一個巨大的瓶頸。任何安全的東西也將非常昂貴。最好檢查一次簽名,然後將其傳送到白名單目錄或數據庫。另一種提高速度的方法是使用較小的RSA密鑰進行簽名。例如,對於SSLv3,一個512位的RSA密鑰足夠好,所以它可能足夠好。

MD5是非常糟糕的。如果您存儲「安全」md5文件哈希的白名單,那麼這將打開collision generation的大門。這是使用md5前綴攻擊的理想情況,因爲特製的二進制數據在文件的開始處不會阻止include()執行php標記<?php ?>內的代碼。

CRC比MD5更糟。 CRC不打算使散列衝突更加困難。 CRC只是爲了檢測隨機噪聲造成的損害。通過將數據a附加到消息a CRC collision can be generated對md5使用類似的攻擊。

sha1是一個安全且快速的哈希函數,您可以使用。有一個類似的哈希碰撞攻擊影響sha1。然而,與md5不同,沒有人生成sha1 collsion和NIST still considers its use to be safe。雖然sha256會是更安全的選擇。

+0

謝謝。我一直在考慮使用sha256公鑰和私鑰。我已經實施了公鑰和私鑰。公鑰存儲在公共存儲庫中,在下載和安裝時檢查密鑰。安裝完成後,將爲每個實例生成一個新的私鑰,並檢查其是否完整。 SHA1原本是我心目中的,但默認爲md5。我想這對我來說是天真的,尤其是考慮到我對md5最近缺乏完整性的瞭解。我將使用SHA256作爲密鑰,如果我最終實現了校驗和,我將使用SHA1。 – Swivel 2010-07-16 05:42:24

+0

再次感謝您的答案。我喜歡公鑰和私鑰的想法,但是我有點猶豫,因爲如果我能夠以經濟高效的方式對文件運行校驗和,那麼我會更喜歡這種方式。我會堅持使用SHA-HASH算法。但是,鑑於我的應用程序的口徑,RSA密鑰簽名會有點多! :P – Swivel 2010-07-16 05:46:44

0

我想檢查每個負載的校驗和是一個壞主意,因爲它會爲你的應用程序肯定放慢。

一種不同的方法是,你把東西在你的應用程序管理界面安裝或啓用該插件。

然後,你可以檢查插件一次安裝時,並將其添加到啓用插件列表,然後才能使用它。

你也可以查看每天一次所有的插件,以檢查是否一個被改變......但它很難做出安全的,因爲任何改變插件,而它被安裝也可以改變你的安全功能。