关键在于:恶意代码的注入、取出到执行,整个过程完全不需要经过服务器后端。
可以从三个层面来拆解:
1. 恶意代码的“驻留地”在浏览器端
传统反射型或存储型XSS,恶意代码会作为HTTP请求的一部分发给服务器,服务器再把带有恶意代码的页面返回给浏览器。
而DOM型XSS的恶意代码,从不离开浏览器。它通常通过URL的#号后面的部分(hash)或?后的参数传入,这些信息浏览器不会自动发给服务器。然后前端JS从location.hash或window.name等本地来源取出数据,再用innerHTML等方式直接插入到页面DOM中。
也就是说,攻击者写的代码(不管是HTML标签还是JS)只存在于当前页面的客户端内存里,服务器全程没参与处理。
2. HTML标签是“载体”,JS是“执行体”
攻击者塞入的常是一个HTML标签,比如:
<img src=x onerror=alert('XSS')>
但浏览器解析这个标签时,onerror属性里的内容就是JS代码,标签的作用是触发JS执行。
当然攻击者也可以直接注入<script>alert(1)</script>,但现代浏览器常会限制直接执行动态插入的<script>,所以用HTML标签的事件属性是更通用的绕过方式。
所以,注入的是HTML结构,目的是让JS运行。这个执行完全由浏览器端的DOM解析引擎完成。
3. 为什么强调“浏览器端”漏洞?
把它归为浏览器端,是为了区分漏洞发生的阶段。
- 如果是服务端漏洞(反射型/存储型),防护重点在后端:过滤输入、编码输出。
- 如果是DOM型漏洞,后端即使做了完美过滤也没用,因为恶意代码根本没过后端,是前端JS不安全地操作DOM造成的,防护必须在客户端:避免使用
innerHTML、document.write等危险方法,或对不可信数据做严格转义。
所以“浏览器端”强调的是:漏洞的根源在前端JS逻辑,修复也必须在前端。
总结
- DOM型XSS属于浏览器端漏洞,是因为攻击者利用的是前端JS对客户端本地数据(如URL)的不安全处理。
- 攻击者注入的HTML标签只是"载具",目的是驱动JS代码执行,而整个攻击链条——数据来源、注入、触发——都在浏览器一侧闭环完成。
- 防护DOM型XSS的重点在于前端代码的安全处理,避免使用危险的DOM操作方法,对所有不可信数据进行严格转义。