OWASP Juice Shop: DOM XSS
本文实验均在个人本地部署、合法授权的 OWASP Juice Shop 靶场环境中完成,仅用于安全学习、漏洞分析与防御研究。
DOM XSS
一 漏洞发现与验证
1.确认可控输入点
在搜索框中输入xss-probe-dom-001,观察搜索结果区域是否回显该字段:

确认用户输入可影响页面DOM。
2.HTML注入验证
在搜索界面输入xss-probe-dom-001,观察回显字段是否加粗:

与上张图对比可知字段明显加粗,被当作HTML内容解析,存在注入点。
3.<script>标签执行验证
在搜索处构建<script>alert(1)</script> 观察是否弹窗:

在开发者工具界面观察到script标签已经进去DOM,但未被执行。
4.事件触发型 JavaScript 执行验证
构造带有错误事件处理器的 HTML 元素:
构造<img src=1 onerror="alert(1)">观察是否弹窗:

弹窗成功,触发JS执行,存在DOM XSS。
二 原理分析
1.Source 与 Sink
DOM XSS 通常可以抽象为:
Source
↓
前端 JavaScript
↓
Sink
↓
HTML / JavaScript 执行
Source:
攻击者可控数据来源,例如:
- URL 参数
- location
- location.hash
- 搜索关键词
Sink:
会把输入当作 HTML 或代码处理的位置,例如:
- innerHTML
- outerHTML
- document.write()
- 某些 HTML 渲染 API
2.本案例的数据流
在搜索框中输入内容
↓
搜索关键字进入 URL / 前端状态
↓
前端 JavaScript 获取搜索关键字
↓
将关键字写入搜索结果 DOM
↓
输入被浏览器按照 HTML 解析
↓
事件处理器触发 JavaScript
↓
形成 DOM XSS
3.HTML 注入与 XSS 的区别
HTML 注入:
<b>test</b>
如果页面显示为粗体,说明浏览器将用户输入作为 HTML 解析。
但是 HTML 注入本身并不一定等于 XSS。
XSS 还要求:用户输入最终能够触发 JavaScript 执行
因此:
HTML 注入≠XSS
但:HTML 注入+可执行 JavaScript=XSS
4.为什么 script 没执行,但事件处理器可以执行
动态插入 DOM 的 script 元素在某些情况下不会自动执行,但浏览器解析 HTML 元素后,其事件处理属性仍可能在相应事件发生时执行 JavaScript。
三 源码分析
1.观察源码

bypassSecurityTrustHtml 是Angular的安全绕过API。
Angular默认模板插值会自动对内容做HTML编码,防止XSS;一旦调用这个方法,就是告诉Angular:这个字符串是可信HTML,不要对它做转义,直接渲染成 DOM。
2.源码修复
移除bypassSecurityTrustHtml:
由:
this.searchValue = this.sanitizer.bypassSecurityTrustHtml(queryParam)
改为:
this.searchValue = queryParam
Angular普通插值 {{ searchValue }} 默认自动HTML编码,输入的< > & " '全部实体编码,只会当成纯文本展示,不会解析HTML标签。

浙公网安备 33010602011771号