PHP代碼審計
2011 年 2 月 13 日
文檔去年做的,按說應該更新了,寫得不咋好,有些沒寫全,參考了很多文檔。
話說owasp codereview,也該出2.0了。
牛們路過,給提點建議。
目錄
1. 概述 3
2. 輸入驗證和輸出顯示 3
2.1 命令注入 4
2.2 跨站腳本 4
2.3 文件包含 5
2.4 代碼注入 5
2.5 SQL注入 6
2.6 XPath注入 6
2.7 HTTP響應拆分 6
2.8 文件管理 6
2.9 文件上傳 7
2.10 變量覆蓋 7
2.11 動態函數 7
3. 會話安全 8
3.1 HTTPOnly設置 8
3.2 domain設置 8
3.3 path設置 8
3.4 cookies持續時間 8
3.5 secure設置 8
3.6 session固定 9
3.7 CSRF 9
4. 加密 9
4.1 明文存儲密碼 9
4.2 密碼弱加密 9
4.3 密碼存儲在攻擊者能訪問到的文件 9
5. 認證和授權 10
5.1 用戶認證 10
5.2 函數或文件的未認證調用 10
5.3 密碼硬編碼 10
6. 隨機函數 10
6.1 rand() 10
6.2 mt_srand()和mt_rand() 11
7. 特殊字符和多字節編碼 11
7.1 多字節編碼 11
8. PHP危險函數 11
8.1 緩沖區溢出 11
8.2 session_destroy()刪除文件漏洞 12
8.3 unset()-zend_hash_del_key_or_index漏洞 12
9. 信息泄露 13
9.1 phpinfo 13
10. PHP環境 13
10.1 open_basedir設置 13
10.2 allow_url_fopen設置 13
10.3 allow_url_include設置 13
10.4 safe_mode_exec_dir設置 14
10.5 magic_quote_gpc設置 14
10.6 register_globals設置 14
10.7 safe_mode設置 14
10.8 session_use_trans_sid設置 14
10.9 display_errors設置 14
10.10 expose_php設置 14
概述
代碼審核,是對應用程序源代碼進行系統性檢查的工作。它的目的是為了找到并且修復應用程序在開發階段存在的一些漏洞或者程序邏輯錯誤,避免程序漏洞被非法利用給企業帶來不必要的風險。
代碼審核不是簡單的檢查代碼,審核代碼的原因是確保代碼能安全的做到對信息和資源進行足夠的保護,所以熟悉整個應用程序的業務流程對于控制潛在的風險是非常重要的。審核人員可以使用類似下面的問題對開發者進行訪談,來收集應用程序信息。
應用程序中包含什么類型的敏感信息,應用程序怎么保護這些信息的?
應用程序是對內提供服務,還是對外?哪些人會使用,他們都是可信用戶么?
應用程序部署在哪里?
應用程序對于企業的重要性?
最好的方式是做一個checklist,讓開發人員填寫。Checklist能比較直觀的反映應用程序的信息和開發人員所做的編碼安全,它應該涵蓋可能存在嚴重漏洞的模塊,例如:數據驗證、身份認證、會話管理、授權、加密、錯誤處理、日志、安全配置、網絡架構。
輸入驗證和輸出顯示
大多數漏洞的形成原因主要都是未對輸入數據進行安全驗證或對輸出數據未經過安全處理,比較嚴格的數據驗證方式為:
對數據進行精確匹配
接受白名單的數據
拒絕黑名單的數據
對匹配黑名單的數據進行編碼
在PHP中可由用戶輸入的變量列表如下:
$_SERVER
$_GET
$_POST
$_COOKIE
$_REQUEST
$_FILES
$_ENV
$_HTTP_COOKIE_VARS
$_HTTP_ENV_VARS
$_HTTP_GET_VARS
$_HTTP_POST_FILES
$_HTTP_POST_VARS
$_HTTP_SERVER_VARS
我們應該對這些輸入變量進行檢查
命令注入
PHP執行系統命令可以使用以下幾個函數:system、exec、passthru、“、shell_exec、popen、proc_open、pcntl_exec
我們通過在全部程序文件中搜索這些函數,確定函數的參數是否會因為外部提交而改變,檢查這些參數是否有經過安全處理。
防范方法:
使用自定義函數或函數庫來替代外部命令的功能
使用escapeshellarg函數來處理命令參數
使用safe_mode_exec_dir指定可執行文件的路徑
跨站腳本
反射型跨站常常出現在用戶提交的變量接受以后經過處理,直接輸出顯示給客戶端;存儲型跨站常常出現在用戶提交的變量接受過經過處理后,存儲在數據庫里,然后又從數據庫中讀取到此信息輸出到客戶端。輸出函數經常使用:echo、print、printf、vprintf、<%=$test%>
對于反射型跨站,因為是立即輸出顯示給客戶端,所以應該在當前的php頁面檢查變量被客戶提交之后有無立即顯示,在這個過程中變量是否有經過安全檢查。
對于存儲型跨站,檢查變量在輸入后入庫,又輸出顯示的這個過程中,變量是否有經過安全檢查。
防范方法:
如果輸入數據只包含字母和數字,那么任何特殊字符都應當阻止
對輸入的數據經行嚴格匹配,比如郵件格式,用戶名只包含英文或者中文、下劃線、連字符
對輸出進行HTML編碼,編碼規范
< <
> >
( (
) )
# #
& &
原文轉自:http://www.sectop.com/?p=111