PHP 安全性:如何滥用编码?
Posted
技术标签:
【中文标题】PHP 安全性:如何滥用编码?【英文标题】:PHP Security: how can encoding be misused? 【发布时间】:2012-10-12 21:48:10 【问题描述】:从这个出色的“UTF-8 all the way through”问题中,我了解到:
很遗憾,您应该验证每个提交的字符串是否有效 UTF-8 在您尝试将其存储或在任何地方使用之前。 php的 mb_check_encoding() 可以解决问题,但您必须使用它 虔诚地。真的没有办法解决这个问题,作为恶意客户端 可以用他们想要的任何编码提交数据,我还没有找到 让 PHP 可靠地为您执行此操作的技巧。
现在,我仍在学习编码的怪癖,我想确切地知道恶意客户端可以做什么来滥用编码。一个人能实现什么?有人可以举个例子吗?假设我将用户输入保存到 mysql 数据库中,或者通过电子邮件发送,如果我不使用 mb_check_encoding
功能,用户怎么会造成伤害?
【问题讨论】:
【参考方案1】:如果我不使用 mb_check_encoding 功能,用户如何造成伤害?
这是关于overlong encodings。
由于 UTF-8 设计的一个不幸的怪癖,如果使用简单的位打包解码器解析,可能会生成与更短的字节序列相同的字符 - 包括单个 ASCII字符。
例如,字符 <
通常表示为字节 0x3C,但也可以使用超长的 UTF-8 序列 0xC0 0xBC(甚至更多冗余的 3 或 4 字节序列)来表示。
如果您采用此输入并在基于 Unicode 的忽略字节的工具中处理它,则可能会避开该工具中使用的任何字符处理步骤。典型的例子是将 0x80 0xBC 提交给 PHP,它具有本机字节字符串。使用htmlspecialchars
对字符<
进行HTML 编码的典型用法在这里会失败,因为不存在预期的字节序列0x3C。因此,脚本的输出仍将包含超长编码的<
,并且任何读取该输出的浏览器都可能将序列 0x80 0xBC 0x73 0x63 0x72 0x69 0x70 0x74 读取为<script
,嘿嘿!跨站脚本。
自古以来就禁止使用超长,现代浏览器也不再允许使用超长。但长期以来,这对 IE 和 Opera 来说都是一个真正的问题,并且不能保证未来每个浏览器都能解决这个问题。当然,这只是一个例子——任何面向字节的工具处理 Unicode 字符串的地方都可能遇到类似的问题。因此,最好的方法是在最早的输入阶段删除所有超长。
【讨论】:
非常有趣,谢谢!这为此事提供了一些启示。作为一个编码菜鸟,我不清楚的是,我该如何测试呢?我需要做什么才能将0xC0 0xBC
提交到我的网站,以便检查漏洞?我假设我不能使用(现代)浏览器,那么用什么来测试呢?我应该使用旧的 Opera 版本吗?以及如何发布这些类型的字符序列?我是像发文字一样发0xC0 0xBC
,还是工作方式不同?
我宁愿发布一个新问题来询问如何test for this【参考方案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
【讨论】:
以上是关于PHP 安全性:如何滥用编码?的主要内容,如果未能解决你的问题,请参考以下文章