应对XSS跨站攻击的基本原则是:“数据内容不能作为代码执行,或者在受控环境中执行。”在上一篇中,知道了如何设计一个iframe单向访问模型,从而把html内容放入受控环境中,使潜在的攻击代码无所作为。在这里,我们再探索如何实现“数据内容不能作为代码执行”这个原则。
在实际的web应用中,需要用户输入各种类型的数据,然后再显示到其他用户查看的页面上。如果这些内容不经过过滤检测,那么内嵌的攻击代码(通常是XSS跨站攻击)就可能盗取用户的资料。然而,在过滤分析中,并不能保证考虑到所有已知和未知的攻击类型。那么,有没有不需要过滤的解决方案呢?
一个最清晰的方案是在页面运行期间,使用element.innerText;如果有value属性的(如input、textarea)使用value。这样的话,数据内容将永远是数据内容。
还有更多的情况是在页面构造期间显示数据内容。这时,就要使用<xmp>标签。网上的许多资料表明<xmp>是被淘汰的标签,建议使用<pre>。可我测试过许多常用、非常用的标签(如<pre>、<code>、<samp>),发现只有<xmp>标签不解析内部的html元素,而且不执行内部的javascript脚本代码。只要我们的数据内容使用<xmp>或多个<xmp>的组合进行封装,那么用户输入的数据内容就不必再进行过滤分析了。
回味一下<xmp>标签为什么是这三个字母的组合,只能看不能读的?因为这样的话,内部数据包含</xmp>的几率就少之又少了。但不能排除攻击代码在数据中间插入</xmp>从而绕过保护。看来,过滤分析还是需要的,但只需要考虑</xmp>这一种情况而已了。