DVWA XSS DOM DOM型XSS通关教程
漏洞简介
DOM 型 XSS 是个比较特殊的存在,攻击过程完全不经过服务器,纯前端搞定的。恶意代码通过 JavaScript 写进 DOM 里执行,服务端日志里都看不到啥异常。
这关主要学怎么利用 DOM 型 XSS。
DOM 型 XSS 原理
流程是这样的:
- 攻击者搞个带恶意代码的 URL
- 用户点进去,请求发到服务器
- 服务器返回正常页面(恶意代码不在里面)
- 浏览器执行 JS,从 URL 里读出恶意代码
- 恶意代码被写进 DOM 执行
服务器日志里看请求,发现不了 XSS 攻击痕迹。
Low 级别
Low 级别没服务端代码,纯前端 JavaScript:
1 | if (window.location.search.indexOf('default') !== -1) { |
URL 参数 default 直接写进 DOM,一点过滤都没有。
攻击方法
测试 XSS:
1 | ?default=<script>alert('XSS')</script> |
![图片占位]
弹窗了,注入成功。
偷 Cookie:
1 | ?default=<script>alert(document.cookie)</script> |
![图片占位]
也可以用 img 标签:
1 | ?default=<img src=x onerror=alert(1)> |
Medium 级别
Medium 在服务端过滤了 <script:
1 | if( stripos( $default, "<script" ) !== false ) { |
但 DOM 型 XSS 又不是只有 <script> 这一种姿势。
攻击方法
用 img 标签:
1 | ?default=<img src=x onerror=alert(1)> |
![图片占位]
用 svg 标签:
1 | ?default=<svg onload=alert(1)> |
闭合 select 标签:
1 | ?default=</option></select><img src=x onerror=alert(1)> |
![图片占位]
过滤 <script 过滤了个寂寞。
High 级别
High 级别用白名单验证:
1 | switch( $_GET[ 'default' ] ) { |
只允许四个值,服务端过滤得挺死。但别忘了 URL 锚点。
攻击方法
# 后面的东西不会发到服务器,但 JavaScript 能读到:
1 | ?default=English#<script>alert(1)</script> |
![图片占位]
服务端只看到 default=English,白名单过了。但前端 JS 读的是整个 URL,后面的恶意代码照样执行。
也可以用 input 标签:
1 | ?default=English#<input onfocus=alert(1) autofocus> |
Impossible 级别
Impossible 级别没特殊代码,但服务端白名单 + 前端转义:
1 | var lang = document.location.href.substring(document.location.href.indexOf("default=") + 8); |
把 < 和 > 转义成 < 和 >,恶意代码就不会被当成 HTML 执行了。
DOM 型 XSS 常见位置
| 位置 | 说明 |
|---|---|
document.location |
URL 参数 |
document.URL |
完整 URL |
document.referrer |
来源页面 |
document.cookie |
Cookie |
window.name |
窗口名称 |
innerHTML |
HTML 内容 |
document.write() |
直接写入 DOM |
eval() |
执行代码 |
小结
DOM 型 XSS 防护要点:
- 前端对动态内容要做 HTML 实体编码
- 能不用
innerHTML、document.write()、eval()就别用 - 用
textContent代替innerHTML - 配好 CSP
- URL 参数别直接塞进 DOM