结合其他选择器时location.hash在jQuery选择器中是否存在DOM XSS漏洞
jQuery选择器拼接location.hash的DOM XSS风险验证
问题起源
使用Checkmarx SAST做静态代码检测时,工具将两类把URL hash值拼接入jQuery选择器的写法标记为客户端DOM XSS风险,对应代码如下:
- 属性选择器拼接写法(示例1)
$('[name=' + location.hash.replace('#', '') + ' ]')
- ID选择器拼接写法(示例2,原文存在语法笔误,已补全加号)
$('#' + location.hash.replace('#', ''))
我最初完全不理解这类写法为什么会触发XSS——毕竟选择器里有固定拼接的前缀片段,尤其是第一种属性选择器的写法。我之前一直以为只有把去掉#的hash值直接传入jQuery构造函数才会有XSS风险,对应代码是:
$(location.hash.replace('#', ''))
这种场景下攻击者确实可以构造恶意hash段触发XSS,比如URL写为https://example.com#<img src="" onerror="alert(1)">就会执行恶意代码。我之前还认为最新版本的jQuery已经完全修复了直接传入$(location.hash)触发漏洞的问题,想知道自己之前的认知到底哪里有遗漏。
实测更新结论
自己动手测试后发现,之前觉得风险最低的属性选择器写法反而风险最高:直接执行$('[name="<img src="" onerror="alert(document.cookie)""/>]')就会弹出cookie提示,直接触发XSS。
同时测试出这类漏洞的利用边界:
- 只有当jQuery选择器以
#开头的ID选择器起始,或者注入点之前已经存在#标识的ID选择器段时,注入的恶意代码才无法被利用 - 反过来,如果选择器以其他类型选择器开头,且注入点之前没有出现过
#开头的ID选择器段,恶意代码就可以被解析执行
举两个对比例子:
- 可被利用的写法:
$('.something <img src="" onerror="alert(document.cookie)""/> #hash'),虽然选择器末尾有ID选择器,但注入点在ID选择器之前,依然可以触发XSS - 无法被利用的写法:
$('#hash <img src="" onerror="alert(document.cookie)""/>'),选择器开头就是ID选择器,后续注入的恶意代码不会被解析执行
待确认问题
想请大家帮忙验证这个测试结论是否准确:是不是所有以#开头的ID选择器作为起始的jQuery选择器拼接场景,都可以判定不存在这类XSS利用风险?
内容的提问来源于stack exchange,提问作者shevisi tamid
相关产品推荐
相关产品推荐

