假设我们有这种形式,用户注入恶意代码的可能部分如下所示
... > ...
我们不能简单地添加标签或javascript:alert(); call,因为value将被解释为一个字符串,而htmlspecialchars会过滤掉<,>,',",所以我们不能用引号关闭这个值.
我们可以使用String.fromCode(.....)来绕过引号,但我仍然无法弹出一个简单的警告框.
有任何想法吗?
此外,重要的是要提到允许人们将HTML或JavaScript注入您的页面(而不是您的数据源)本身不会带来固有的安全风险.已经存在允许您修改网页上的DOM和脚本的浏览器扩展,但由于它只是客户端,因此它们是唯一知道的.
XSS成为问题的地方是人们a)使用它绕过客户端验证或输入过滤或b)当人们使用它来操纵输入字段时(例如,更改ACL中的OPTION标签的值以授予他们权限)不应该).防止这些攻击的唯一方法是在服务器端清理和验证输入,而不是客户端验证,或者除了客户端验证之外.
要从输入中清除HTML,除非您想要允许某些标记,否则htmlspecialchars是完全足够的,在这种情况下您可以使用像HTMLPurifier这样的库.如果您将用户输入放在HREF,ONCLICK或允许编写脚本的任何属性中,那么您只是在寻找麻烦.
编辑:看看你的代码,看起来你没有引用你的属性!那太傻了.如果有人将其用户名设为:
john onclick="alert('hacking your megabits!1')"
然后你的脚本将解析为:
总是在属性周围使用引号.即使他们不是用户输入,也是一个很好的习惯.
有一种方法.您没有传递htmlspecialchars()第三个编码参数或正确检查编码,因此:
$source = ''; $source = mb_convert_encoding($source, 'UTF-7'); $source = htmlspecialchars($source); //defaults to ISO-8859-1 header('Content-Type: text/html;charset=UTF-7'); echo '' . $source . '';
仅适用于以下情况:a)将页面设置为输出UTF-7或b)欺骗页面执行此操作(例如,页面上的iframe没有明确的字符集集).解决方案是确保所有输入都具有正确的编码,并且在htmlspecialchars()上正确设置了预期的编码.
这个怎么运作?在UTF-7中,<>"字符具有与UTF-8/ISO/ASCII不同的代码点,因此除非将输出转换为UTF-8以进行保证,否则它们不会被转义(请参阅iconv扩展名).