攻击者可以通过构造恶意 URL 注入任意 JavaScript 代码,具体步骤如下:
1. 漏洞利用原理
原代码中动态拼接了 location.href
的参数值到 HTML 中:
document.write('<option value=1>' + location.href.substring(location.href.indexOf('default=') + 8) + '</option>');
如果 URL 中的 default=
参数包含恶意脚本,浏览器会将其解析为可执行的 JavaScript。
2. 攻击步骤
场景示例
假设正常 URL:
https://example.com/page.html?default=en
渲染结果为:
<select>
<option value=1>en</option> <!-- 正常输出 -->
<option value=2>English</option>
</select>
攻击者构造的恶意 URL
将 default=
参数改为以下内容(URL编码可选):
https://example.com/page.html?default=</option></select><script>alert('XSS')</script>
或编码后:
https://example.com/page.html?default=%3C/option%3E%3C/select%3E%3Cscript%3Ealert('XSS')%3C/script%3E
最终生成的恶意 HTML
<select>
<option value=1></option></select><script>alert('XSS')</script></option>
<option value=2>English</option>
</select>
浏览器会解析并执行 <script>alert('XSS')</script>
,导致 XSS。
3. 关键攻击手段
- 闭合标签:通过
</option></select>
提前结束原有标签,释放上下文。 - 注入脚本:插入
<script>
或其他可执行代码(如<img src=x onerror="alert(1)">
)。 - 绕过过滤:使用编码、换行符或特殊字符混淆(如
\u003cscript\u003e
)。
4. 潜在危害
- 窃取数据:通过
document.cookie
盗取用户会话。 - 钓鱼攻击:伪造登录页面。
- 蠕虫传播:自动转发恶意 URL。
5. 防御措施
(1)输入转义
对动态内容进行 HTML 实体编码:
function escapeHTML(str) {
return str.replace(/[&<>'"]/g,
tag => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[tag]));
}
const safeParam = escapeHTML(urlParam);
(2)使用安全 API
避免直接操作 HTML,改用 DOM API:
const select = document.querySelector('select');
const option = document.createElement('option');
option.textContent = urlParam; // textContent会自动转义
select.appendChild(option);
(3)白名单验证
仅允许预定义的参数值:
const allowedValues = ['en', 'zh'];
if (!allowedValues.includes(urlParam)) {
urlParam = 'en'; // 默认值
}
(4)启用 CSP(内容安全策略)
HTTP Header 限制脚本来源:
Content-Security-Policy: default-src 'self'; script-src 'self'
总结
- 攻击本质:利用未转义的动态内容篡改 DOM。
- 修复核心:始终对用户输入进行转义或隔离(如 Shadow DOM)。
内容由零声教学AI助手提供,问题来源于学员提问