从这个出色的“UTF-8 all the way through”问题中,我读到以下内容:
现在,我仍在学习编码的怪癖,并且我想确切地知道恶意客户端可以采取什么措施来滥用编码。一个人能实现什么?有人可以举个例子吗?假设我将用户输入保存到MySQL数据库中,或者通过电子邮件发送,如果不使用mb_check_encoding
功能,用户怎么可能造成伤害?
最佳答案
这是关于overlong encodings。
由于UTF-8设计的一个令人遗憾的怪癖,如果使用天真的位打包解码器进行解析,可能会产生与较短的字节序列相同的字符,包括单个ASCII字符,从而使字节序列成为可能。
例如,字符<
通常表示为字节0x3C,但也可以使用超长UTF-8序列0xC0 0xBC(或更冗余的3或4字节序列)表示。
如果您接受此输入并在基于Unicode的基于字节的工具中对其进行处理,则可以逃避该工具中正在使用的任何字符处理步骤。规范的示例是将0x80 0xBC提交给具有本地字节字符串的PHP。由于不存在预期的字节序列0x3C,通常无法使用htmlspecialchars
对字符<
进行HTML编码。因此,脚本的输出仍将包含超长编码的<
,并且任何读取该输出的浏览器都可能将序列0x80 0xBC 0x73 0x63 0x72 0x69 0x70 0x74读为<script
,嘿! XSS。
自从过去以来,就禁止使用长号,而现代的浏览器不再允许使用长号。但这对于IE和Opera而言,长期以来一直是一个真正的问题,并且不能保证每种浏览器将来都能正确实现。当然,这只是一个示例-在任何面向字节的工具处理Unicode字符串的地方,您都可能遇到类似的问题。因此,最好的方法是在最早的输入阶段删除所有的加长部分。