注意,对于使用 OpenBSD 和 PHP 的用户。默认的 php.ini 有 display_errors=off。这与 PHP 默认的 display_errors=on 相反。如果您在 OpenBSD 上无法看到错误,请确保将 php.ini 编辑为 display_errors=on。(我在 OpenBSD 4.4 上遇到了这个问题)
在 PHP 安全方面,错误报告有两面性。一面有利于提高安全性,另一面则是有害的。
一种常见的攻击策略是通过向系统提供不正确的数据进行分析,并检查返回的错误类型和上下文。这允许系统破解者探测有关服务器的信息,以确定可能的弱点。例如,如果攻击者根据先前的表单提交获得了有关页面的信息,他们可能会尝试覆盖变量或修改它们。
示例 #1 使用自定义 HTML 页面攻击变量
<form method="post" action="attacktarget?username=badfoo&password=badfoo"> <input type="hidden" name="username" value="badfoo" /> <input type="hidden" name="password" value="badfoo" /> </form>
PHP 通常返回的错误对于试图调试脚本的开发人员来说非常有用,可以指示诸如失败的函数或文件、失败的 PHP 文件以及发生失败的行号之类的信息。所有这些信息都可以被利用。php 开发人员通常使用 show_source()、highlight_string() 或 highlight_file() 作为调试措施,但在实时站点中,这可能会暴露隐藏的变量、未检查的语法和其他危险信息。尤其危险的是运行来自具有内置调试处理程序的已知来源的代码,或者使用常见的调试技术。如果攻击者能够确定您使用的是什么通用技术,他们可能会尝试通过发送各种常见的调试字符串来暴力破解页面。
示例 #2 利用常见的调试变量
<form method="post" action="attacktarget?errors=Y&showerrors=1&debug=1"> <input type="hidden" name="errors" value="Y" /> <input type="hidden" name="showerrors" value="1" /> <input type="hidden" name="debug" value="1" /> </form>
无论采用何种错误处理方法,探测系统以查找错误的能力都会导致攻击者获得更多信息。
例如,通用 PHP 错误的风格本身就表明系统正在运行 PHP。如果攻击者查看一个 .html
页面,并且想要探测后端(以查找系统中已知的弱点),通过提供错误的数据,他们可能能够确定系统是用 PHP 构建的。
函数错误可以指示系统是否可能正在运行特定的数据库引擎,或者提供有关网页或程序设计或设计的线索。这允许对开放的数据库端口进行更深入的调查,或者查找网页中的特定错误或弱点。通过提供不同的错误数据片段,例如,攻击者可以确定脚本中身份验证的顺序(从行号错误),以及探测可能在脚本中不同位置利用的漏洞。
文件系统或通用 PHP 错误可以指示 Web 服务器拥有哪些权限,以及 Web 服务器上文件结构和组织。开发人员编写的错误代码会加剧这个问题,导致以前“隐藏”的信息很容易被利用。
这个问题有三个主要解决方案。第一个是仔细检查所有函数,并尝试弥补大多数错误。第二个是完全禁用运行代码中的错误报告。第三个是使用 PHP 的自定义错误处理函数创建自己的错误处理程序。根据您的安全策略,您可能会发现所有这三种方法都适用于您的情况。
提前捕获此问题的其中一种方法是利用 PHP 自己的 error_reporting() 来帮助您保护代码并查找可能存在安全风险的变量使用情况。在部署之前,通过使用 E_ALL
测试您的代码,您可以快速找到变量可能被污染或以其他方式修改的地方。准备部署后,您应该通过将 error_reporting() 设置为 0 来完全禁用错误报告,或者使用 php.ini 选项 display_errors
关闭错误显示,以保护您的代码免受探测。如果您选择后者,您还应该使用 error_log
ini 指令定义日志文件的路径,并将 log_errors
打开。
示例 #3 使用 E_ALL 查找危险变量
<?php
if ($username) { // 在使用之前未初始化或检查
$good_login = 1;
}
if ($good_login == 1) { // 如果上面的测试失败,则在使用之前未初始化或检查
readfile ("/highly/sensitive/data/index.html");
}
?>
注意,对于使用 OpenBSD 和 PHP 的用户。默认的 php.ini 有 display_errors=off。这与 PHP 默认的 display_errors=on 相反。如果您在 OpenBSD 上无法看到错误,请确保将 php.ini 编辑为 display_errors=on。(我在 OpenBSD 4.4 上遇到了这个问题)