PHP安全:如何滥用编码?

2022-08-30 22:21:43

从这个优秀的“UTF-8一路走来”的问题,我读到了这个:

遗憾的是,在尝试存储每个字符串或在任何地方使用它之前,您应该验证每个提交的字符串是否为有效的 UTF-8。PHP的mb_check_encoding()可以解决问题,但你必须虔诚地使用它。这真的没有办法解决这个问题,因为恶意客户端可以用他们想要的任何编码提交数据,我还没有找到让PHP可靠地为你做到这一点的技巧。

现在,我仍在学习编码的怪癖,我想知道恶意客户端可以做些什么来滥用编码。一个人能实现什么目标?有人能举个例子吗?假设我将用户输入保存到MySQL数据库中,或者我通过电子邮件发送,如果我不使用该功能,用户如何造成伤害?mb_check_encoding


答案 1

如果我不使用mb_check_encoding功能,用户如何造成伤害?

这是关于过长的编码

由于 UTF-8 设计的一个不幸的怪癖,可以制作字节序列,如果使用朴素的位打包解码器进行解析,则会导致与较短的字节序列相同的字符 - 包括单个 ASCII 字符。

例如,字符通常表示为字节0x3C,但也可以使用过长的 UTF-8 序列0xC0 0xBC(甚至更冗余的 3 或 4 字节序列)来表示。<

如果您采用此输入并在 Unicode 遗忘的基于字节的工具中处理它,则可能会规避该工具中使用的任何字符处理步骤。规范示例是将0x80 0xBC提交给 PHP,PHP 具有本机字节字符串。此处,对字符进行 HTML 编码的典型用法将失败,因为预期的字节序列0x3C不存在。因此,脚本的输出仍将包含超长编码,并且任何读取该输出的浏览器都可能读取序列0x80 0xBC 0x73 0x63 0x72 0x69 0x70 0x74 as 和 hey presto!新浪网.htmlspecialchars<<<script

自很久以前以来,超长已被禁止,现代浏览器不再允许它们。但长期以来,这对IE和Opera来说都是一个真正的问题,并且不能保证每个浏览器将来都会正确使用。当然,这只是一个例子 - 任何一个面向字节的工具处理Unicode字符串的地方,你都可能遇到类似的问题。因此,最好的方法是在最早的输入阶段删除所有超长。


答案 2

似乎这是一个复杂的攻击。检查文档可注明“无效编码攻击”。谷歌搜索“无效编码攻击”会带来一些有趣的结果,我将尝试解释这些结果。mb_check_encoding

当这种数据发送到服务器时,它将执行一些解码来解释正在发送的字符。现在,服务器将执行一些安全检查,以查找某些可能有害的特殊字符的编码版本。

当向服务器发送无效编码时,服务器仍会运行其解码算法,并将评估无效编码。这就是出现问题的地方,因为安全检查可能不会查找在通过解码算法运行时仍会产生有害字符的无效变体。

在 unix 系统上请求完整目录列表的攻击示例:

http://host/cgi-bin/bad.cgi?foo=..%c0%9v../bin/ls%20-al|

如果您想更详细地解释算法中发生的事情,这里有一些链接:

http://www.cgisecurity.com/owasp/html/ch11s03.html#id2862815

http://www.cgisecurity.com/fingerprinting-port-80-attacks-a-look-into-web-server-and-web-application-attack-signatures.html


推荐