赞
踩
普通的 XSS,是通过服务端(比如模板技术)将数据输出到 HTML 中。而 DOM Based 类型 的 XSS,是通过 JS 将数据输出到 HTML 中。
请看下例:
<script type="text/javascript">
var x='<来源于 input 输入框>';
document.write("<a href='"+x+"'>demo</a>")
</script>
这里的 x 变量,其值来源于用户所输入的内容。网站开发者使用普通 XSS 的防御方法(DefaultEncoder.getInstance().encodeForJavaScript(str)
)对该变量进行编码,以避免 XSS 攻击。
假设,攻击者使用 'onclick=alert('dom_based_xss');//'
作为输入内容,那么经过 encodeForJavaScript 编码,变量 x 变为这样:
<script type="text/javascript">
var x='\x27onclick\x3Dalert\x28\x27dom_based_xss\x27\x29\x3B\x2F\x2F\x27';
document.write("<a href='"+x+"'>demo</a>")
</script>
攻击结果:
难道 ESAPI 也防御不了基于 DOM Based 类型的 XSS 攻击了吗?我们来分析分析。
这是因为 encodeForJavaScript 只能保护 JS。而编码过的恶意脚本,通过 document.write()
方法输出到 HTML 页面时,又会被解码还原回去,从而导致 XSS 攻击成功。
那是否对上述场景应用 HtmlEncode 就解决问题了呢?请看下面这一段代码:
var y=xxx';
document.write("<a href=# onclick='alert(\""+y+"\")'>demo2</a>");
假设攻击者编写的攻击字符串是这样的:正常逻辑");alert('dom_based_xss');///
,经过 HtmlEncode 编码为:正常逻辑");alert('dom_based_xss');///
攻击结果:
第一次仍然会执行正常逻辑,第二次就被 XSS 注入攻击咯。所以单纯使用 HtmlEncode 编码,仍然防不住被攻击。
终极防御方法为:输出到 <script>
时,先使用 encodeForJavaScript 对其编码。然后在 doucment.write() 方法中做判断,如果是输出到 HTML 页面,则再使用 encodeForHTML 二次编码;如果是输出到 JavaScript,则使用 encodeForJavaScript 二次编码。这样,才能确保万无一失。
可能发生 DOM Based 类型的 XSS 攻击,有以下这些方法:
以下这些地方有可能成为 DOM Based 类型的 XSS 攻击字符串的注入点,也需要注意防范:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。