简短的问题:
问题:如果服务器以 UTF-8 运行 htmlentities 但客户端将结果视为 ISO-8859-1,是否会出现任何安全漏洞?
假设:使用一个一致的字符集时不存在漏洞
详细问题:
问题:如果服务器 htmlentities 将 ISO-8859-1 字符串作为 UTF-8,是否会出现任何安全漏洞?(并且客户端将结果解释为 ISO-8859-1?)
(例如$results = htmlentities($iso_8859_1_string, ENT_QUOTES, "UTF-8")
假设所有内容都以这样一种方式编码,即当始终使用一种字符集编码时不会出现漏洞。(忽略 $results = 空字符串)。
也许如果$iso_8859_1_string
可以包含任何值,则结果将被视为无效的 UTF-8(并返回“”)或有效的 UTF-8。对于有效的 UTF-8,UTF-8 序列将按预期转义,但在将结果解释为 ISO-8859-1 的客户端上如何查看结果?0 - 127 范围内的字符按预期转义(与“US-ASCII”相同),某些字符将解析为 html 实体并可以按预期显示。在 128+ 范围内是否存在无法解析为 html 实体的有效 UTF-8 字符?客户端会不会只看到一堆乱码/垃圾文本/符号,但看不到会导致 Web 浏览器执行代码或切换到代码执行上下文的字符?(例如,没有标签字符,例如'<' '>' 符号)?(假设 $results 被放入一个 "
这是正确的思路吗?
注意:我相信我已经解决了反之亦然的情况(即,如果服务器将 UTF-8 字符串作为 ISO-8859-1 并且客户端将结果解释为 UTF-8)
(例如htmlentities($utf8_string, ENT_QUOTES, "ISO-8859-1")
)
回答:我的猜测是客户端上没有安全漏洞(对于 htmlentities 作为 ISO -> 客户端读取为 UTF-8),因为:
在 ISO-8859-1 中,范围内的字符:
- 0-127 (US-ASCII):在 UTF-8 中以完全相同的方式编码,
- ISO-8859-1 中的 160 -> 255 都将被编码为 HTML 实体,
- 只留下 128-159 字符范围...,但根据 Wikipedia 的 UTF-8 规范http://en.wikipedia.org/wiki/UTF-8#Description,所有 UTF-8 字节都在 128+范围都是“多字节序列”的一部分,其中包括始终为 192 或更高的“前导字节”和 128+ 范围内的“连续字节”。因此,
htmlentities($utf8_string, ENT_QUOTES, "ISO-8859-1")
无法输出 UTF-8 生成有效多字节序列所需的任何“前导字节”。因此,此范围内的任何字符都会在 UTF-8 中显示为 ? (即无效字符),因为没有看到任何“前导字节”。
我认为这解决了我对另一个方向的问题。
实际情况:具有安全反向端口的 PHP 5.3.x 服务器使用 ISO-8859-1 作为默认编码。从 PHP 5.4 开始,UTF-8 是默认编码。 http://php.net/htmlentities。我想确定代码是否在全 UTF-8 或全 ISO-8859-1 环境中正常工作,并确保不存在由编码错误/不匹配引起的自动安全漏洞。
我觉得我可以放心,只有可用性会受到影响,而在这些特定情况下不会影响安全性。