DVWA Medium DOM XSS安全测试与防护分析

DVWA Medium DOM XSS安全测试与防护分析 注意有关DOM XSS漏洞的基础知识与原理已在上篇文章指出此处不再解释。可参考该文章https://www.cnblogs.com/lky-sec/articles/21412117本文仅用于网络安全学习与防御研究。所有测试均在本人本地部署、合法授权的 DVWA 靶场中进行禁止将相关方法用于任何未授权系统。一 测试范围与环境本次测试目标为本地DVWA靶场中的XSSDOM模块。项目配置测试环境本地 DVWA 靶场安全等级Medium测试系统Kali Linux测试工具Firefox、Burp Suite测试方式黑盒测试、源码审计授权情况本人本地靶场合法授权二 页面与请求分析1. 设置难度等级进入 DVWA Security将安全等级设置为 Medium随后进入 XSSDOM模块。2. 观察模块正常功能页面提供语言选择下拉框可以选择 English、French、Spanish、German 等语言。选择不同语言后可以观察到浏览器地址栏中的default参数发生变化。3. 分析URL参数与DOM变化也可使用浏览器开发者工具进行查看页面源码开启Burp Suite Proxy模块进行拦截提交一次正常请求。右键将正常请求发送到 Burp Suite Repeater。发送请求观察Response包页面源码。发现程序首先通过document.location.href获取当前页面URL并查找其中的default参数var lang document.location.href.substring( document.location.href.indexOf(default)8 );随后通过document.write(option value lang decodeURI(lang) /option);将default参数对应的内容动态写入页面DOM。因此该模块的数据流可以表示为URL中的default参数 ↓ document.location.href读取 ↓ substring()提取参数内容 ↓ document.write()写入页面DOM这说明default参数属于用户可控数据并会直接影响页面DOM结构三 手工黑盒测试1.测试Low难度Payload输入scriptalert(x)/script无弹窗且URL处返回English。将该命令大小写混合输入ScRiPtalert(x);/ScRiPt无弹窗且URL处返回English。结合两次输入即其对应返回结果猜测此处对script标签进行过滤且不区分大小写。2.使用不依赖script标签的HTML事件属性HTML 中部分元素支持事件属性例如onclick onload onerror这些属性会在对应事件发生时执行其中的 JavaScript因此 JavaScript 并不一定必须写在script标签内部。例如输入img srcx onerroralert(x)其中imgHTML 图片标签。 srcx指定一个通常无法正常加载的图片地址 x。 onerror图片加载失败时触发的错误事件。 alert(x)事件触发后执行的 JavaScript 代码。其执行过程为img标签被浏览器解析 ↓ 浏览器尝试加载srcx ↓ 图片加载失败 ↓ 触发onerror事件 ↓ 执行alert(x)提交后未出现弹窗。结合前端 JavaScript 可以发现default参数最终通过document.write()被写入option元素内部因此img标签仍处于select结构中无法作为正常图片元素触发 onerror 事件。因此需要先闭合原有的 option 和 select 标签使后续 HTML 内容脱离下拉框结构。3.脱离下拉框结构输入/option/selectimg srcx onerroralert(x)或者/selectimg srcx onerroralert(x)弹窗成功四 黑盒测试结果分析测试Payload测试结果结果分析scriptalert(x)/script未弹窗URL返回EnglishLow难度Payload失效说明Medium等级增加了针对script标签的限制ScRiPtalert(x);/ScRiPt未弹窗URL仍返回English改变大小写后仍被限制初步判断过滤规则对script标签匹配不区分大小写img srcx onerroralert(x)未弹窗Payload未使用script标签但由于内容仍位于select/option结构中img标签无法作为正常图片元素执行/option/selectimg srcx onerroralert(x)成功弹窗通过闭合原有DOM结构使img标签脱离下拉框并正常触发onerror事件/selectimg srcx onerroralert(x)成功弹窗浏览器能够自动结束当前option元素仅闭合select同样可以脱离原有DOM结构并执行事件代码五 代码审计1. 查看Medium源码点击view source查看源码?php // Is there any input? if ( array_key_exists( default, $_GET ) !is_null ($_GET[ default ]) ) { $default $_GET[default]; # Do not allow script tags if (stripos ($default, script) ! false) { header (location: ?defaultEnglish); exit; } } ?2. 源码分析Medium 等级首先获取用户通过 URL 提交的 default 参数$default $_GET[default];随后使用stripos($default, script)检测参数中是否包含 script 字符串。stripos() 进行的是不区分大小写的字符串查找因此script ScRiPt SCRIPT均能够被检测到。当发现参数中存在script时程序执行header (location: ?defaultEnglish); exit;将页面重新重定向至?defaultEnglish这与前面黑盒测试中普通script和大小写混合ScRiPt均被重定向至 English 的现象一致。但该防护仅针对script字符串进行检测并没有限制其他 HTML 标签或事件属性。因此不包含script的内容不会触发该过滤规则例如img srcx onerroralert(x)结合前面已经分析的前端 document.write()此类内容仍可能被写入页面 DOM 并被浏览器解析。因此该漏洞的主要原因是Medium 等级仅通过 stripos() 对 script 标签进行黑名单检测防护范围有限未从根本上阻止用户可控数据进入 DOM 结构。3. 修复方案1对 default 参数采用白名单校验仅允许 English、French、Spanish、German 等合法值。2避免使用 document.write() 将用户可控数据直接写入 DOM。3使用 textContent、createElement() 等安全 DOM API 生成页面内容。4对需要输出到页面的动态数据进行上下文相关编码。5避免使用 stripos() 等黑名单方式过滤特定标签或关键字。6配置合理的 Content Security PolicyCSP限制内联脚本和事件属性执行。7对异常 default 参数及可疑 XSS 请求进行日志记录与安全监控。六 Low与Medium差异对比项LowMedium服务端防护无增加服务端检测逻辑default参数处理不处理获取$_GET[default]并进行检查过滤方式无使用stripos()检测script是否区分大小写不涉及不区分大小写遇到script时的处理不拦截重定向到?defaultEnglish普通scriptalert(x)/script可利用被拦截大小写混合ScRiPt.../ScRiPt可利用仍被拦截非script型 Payload可利用仍可能利用HTML 事件属性利用可利用仍可能通过onerror等方式绕过DOM 写入根因用户输入可进入 DOM用户输入仍可进入 DOM主要防护措施无任何防护仅对script进行黑名单检测主要安全问题用户输入可直接影响 DOM 结构黑名单检测范围有限未从根本上阻止用户输入进入 DOM漏洞是否存在存在仍然存在根本修复方式避免将用户输入直接写入 DOM并采用白名单校验避免将用户输入直接写入 DOM并采用白名单校验