我正在研究编码字符串以防止XSS攻击.现在我们想要使用白名单方法,其中白名单之外的任何字符都将被编码.现在,我们正在采取'('和输出'('之类的东西.据我们所知,这将阻止大多数XSS.
问题是我们有很多国际用户,当整个网站都是日文版时,编码成为主要的带宽需求.可以肯定地说,基本ASCII集之外的任何字符都不是漏洞而且它们不需要编码,或者是否仍然需要编码的ASCII集之外的字符?
如果你只是将编码传递给htmlentities()/htmlspecialchars,可能会(很多)更容易
echo htmlspecialchars($string, ENT_QUOTES, 'utf-8');
但是,如果这是足够的或取决于你打印什么(和在哪里).
另见:
http://shiflett.org/blog/2005/dec/googles-xss-vulnerability
http://jimbojw.com/wiki/index.php?title=Sanitizing_user_input_against_XSS
http://www.erich-kachel.de /?p = 415(用德语.如果我发现类似的英文 - >更新)编辑:好吧,我想你可以得到主要点而不会流利的德语;)字符串
javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41))传递htmlentities()不变.现在考虑类似的事情
哪个会发送到浏览器.归结为href="javascript:eval(\"alert('XSS')\")"虽然htmlentities()可以完成元素内容的工作,但对于属性来说并不是那么好.
2> Daniel Marti..:一般来说,是的,你可以依赖任何非ascii是"安全的",但有一些非常重要的警告要考虑:
始终确保您发送给客户端的内容标记为UTF-8.这意味着在每个页面上都有一个标题显示"Content-Type:text/html; charset = utf-8"的标题,包括所有错误页面,如果这些错误页面上的任何内容是从用户输入生成的.(许多人忘记测试他们的404页面,并且该页面包含未逐一找到的URL)
始终确保您发送给客户的内容是有效的UTF-8.这意味着您 不能简单地将从用户收到的字节再次传递给用户.您需要将字节解码为UTF-8,应用您的html编码XSS预防,然后在将它们写回时将它们编码为UTF-8.
这两个警告中的第一个是让客户端的浏览器看不到包含高字母字符和回退到某些本地多字节字符集的东西.该本地多字节字符集可能有多种方法来指定您无法防范的有害ascii字符.与此相关,某些浏览器的某些旧版本 - 咳嗽即咳嗽 - 在检测到页面为UTF-7时有点过于苛刻; 这开启了XSS可能性的终结.为了防止这种情况,您可能需要确保对任何传出的"+"符号进行html编码; 当你生成正确的Content-Type标题时,这是过度的偏执,但是当一些未来的人翻转关闭你的自定义标题的开关时,它会保存你.(例如,通过在应用程序前放置配置不当的缓存反向代理,或者通过执行某些操作来插入额外的标题标头 - 如果已经写入任何输出,php将不允许您设置任何HTTP标头)
第二个是因为在UTF-8中可以指定"过短"序列,虽然在当前规范下无效,但旧版浏览器会将其解释为ASCII字符.(看看维基百科有什么说法)另外,有人可能会在请求中插入一个坏字节; 如果你将这个包传递给用户,它可能会导致某些浏览器用"?"替换坏字节和后面的一个或多个字节.或其他一些"无法理解这个"的角色.也就是说,一个坏字节可能会导致一些好的字节被吞没.如果你仔细观察你输出的内容,可能会有一个地方,一个能够从输出中擦除一两个字节的攻击者可以做一些XSS.将输入解码为UTF-8然后对其进行重新编码可防止此攻击向量.