从这个出色的“UTF-8 all the way through”问题中,我读到了这个问题:
不幸的是,您应该验证每个提交的字符串是否有效 UTF-8尝试存储或在任何地方使用它之前。 PHP的 mb_check_encoding()可以解决问题,但你必须使用它 宗教。真的没办法解决这个问题,作为恶意客户 可以以他们想要的任何编码提交数据,但我还没有找到 让PHP为您可靠地执行此操作的技巧。
现在,我仍然在学习编码的怪癖,而且我想知道恶意客户端可以做些什么来滥用编码。一个人可以实现什么?有人能举个例子吗?假设我将用户输入保存到MySQL数据库中,或者通过电子邮件发送,如果我不使用mb_check_encoding
功能,用户怎么会造成伤害?
答案 0 :(得分:13)
如果我不使用mb_check_encoding功能,用户如何造成伤害?
这大约是overlong encodings。
由于UTF-8设计的一个不幸的怪癖,可以制作字节序列,如果使用朴素的位打包解码器进行解析,则会产生与较短字节序列相同的字符 - 包括单个ASCII字符。
例如,字符<
通常表示为字节0x3C,但也可以使用超长UTF-8序列0xC0 0xBC(甚至更冗余的3或4字节序列)来表示。
如果您使用此输入并在基于Unicode的遗忘的基于字节的工具中处理它,则可以避免在该工具中使用的任何字符处理步骤。规范的例子是向PHP提交0x80 0xBC,它具有本机字节字符串。 htmlspecialchars
对字符<
进行HTML编码的典型用法将在此处失败,因为预期的字节序列0x3C不存在。所以脚本的输出仍然包括超长编码的<
,并且读取该输出的任何浏览器都可能读取序列0x80 0xBC 0x73 0x63 0x72 0x69 0x70 0x74为<script
并且嘿presto! XSS。
自从回归以来,已经禁止了Overlongs,现代浏览器不再允许它们。但这对IE和Opera来说是一个真正的问题很长一段时间,而且不能保证每个浏览器都能在未来做到正确。当然,这只是一个例子 - 任何一个面向字节的工具处理Unicode字符串的地方,你可能会遇到类似的问题。因此,最好的方法是在最早的输入阶段删除所有切入点。
答案 1 :(得分:4)
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