几天来,我试图弄清楚如何用 php 编写一个安全的 Web 应用程序,结果发现它特别困难。我读得越多,我就越陷入充满漏洞的深渊,像马特·罗宾逊或克里斯·希夫莱特这样的好心人没有提到这些漏洞。
举几个例子:
- http://sirdarckcat.blogspot.de/2009/10/couple-of-unicode-issues-on-php-and.html
- https://www.owasp.org/index.php/Double_Encoding
- 另请参阅 Rook 的回答中的角色消耗
简而言之,我看到以下问题:
- 在过滤输入时,不太清楚以后如何解码该数据,因此字符编码和转义系统可以绕过输入过滤。(如双url解码)
- 转义输出时,使用标准函数,例如htmlspecialchars。htmlspecialchars 有一个编码参数很好,但这并不妨碍您向它发送 UTF-16 输入,这可能会破坏函数的安全值。
php 中似乎有一个 mbstring 模块,但如果它的安全性与它的文档一样容易理解,那么即使我能弄清楚如何使用它,它也可能毫无用处。只是用于说明的文档示例:
mbstring.strict_detection boolean
Enables the strict encoding detection.
太好了,这很有帮助。
不幸的是,这些功能还取决于您在配置选项中设置的内容......似乎有一个mb_convert_encoding
名为)。还有mb_check_encoding
。这似乎是为了目的,但阅读用户对文档的评论并不能完全激发信心。
所以问题是,鉴于这一切,您如何进行安全输入过滤?像这样的东西?
mb_convert_encoding
转为 UTF-8mb_check_encoding
拒绝无效输入- 循环 url_decode 直到字符串停止变化
- 使用文本比较和正则表达式等进行正常输入过滤...
编辑:请注意,3 是有问题的,因为您的正常输入过滤可能会再次引入可以进行 url 解码的实体
编辑我在这里
找到了部分答案,来自希夫莱特。似乎对于 htmlspecialchars 使用它的 encoding 参数并确保将浏览器的字符编码标头设置为相同可以避免浏览器对字符的解释与 htmlspecialchars 不同。这一切都假设 htmlspecialchars 的输入对于给定的编码是有效的,或者对于每个可能的无效输入 htmlspecialchars 以与每个浏览器完全相同的方式解释字符串。我们知道,如果我们无法清理我们的输入,我们就无法确保 htmlspecialchars 的输入是有效编码的,因为攻击者可能会使用无效编码来编造一个字符串。这将我们引向第二种可能性,对于所有可能的输入,htmlspecialchars 的行为将与浏览器相同。这是个问题,
这一切都类似于 msql_real_escape 对数据库所做的事情,尽管我认为您可以通过使用准备好的语句来正确解决 msql 的这个问题。
第三个有问题的输出是使用 php 进行文件上传或其他文件系统操作时的文件系统。关于最后一个,似乎可用的信息很少。我什至不知道一个特定的转义函数,更不用说当它得到弯曲输入时的健壮性了。