当你的网站突然收到一串包含 <script>alert(1)</script> 的请求参数,这或许是最常见的XSS攻击载荷测试。但真正的攻击者不会止步于此——他们可能使用编码、拼接、事件属性等技巧绕过过滤。本文从实际问题切入,分析XSS攻击载荷的常见模式,帮你练就识别危险输入特征的实战能力。
常见XSS载荷模式与识别要点
XSS攻击载荷的核心是让浏览器执行非预期的脚本。识别危险输入,首先要理解载荷的几种典型形态:
- 直接脚本注入:如
<script>alert(document.cookie)</script>,特征明显,但容易被过滤。 - 事件属性:如
<img src=x onerror=alert(1)>,利用标签事件触发,常见于富文本输入。 - 伪协议:如
<a href=javascript:alert(1)>click</a>,在链接中嵌入可执行代码。 - 编码绕过:如
<script>或%3Cscript%3E,通过HTML实体或URL编码隐藏特征。
识别时,不要只盯 script 标签,更要关注标签事件(如 onerror、onclick)和危险协议(如 javascript:)。例如,一个 <svg onload=alert(1)> 同样危险。
危险输入特征:从数据流角度判断
判断输入是否危险,不能只看内容,还要看它流向哪里。危险输入通常具备以下特征:
- 未经验证直接进入HTML上下文:如用户输入被拼接到
innerHTML或document.write。 - 出现在URL属性中:如
<a href="用户输入">,若未过滤javascript:协议,可被利用。 - 作为CSS值使用:如
style="background:url(用户输入)",可能触发CSS注入。 - 被反射到响应中:如搜索关键词直接回显在页面,未做输出编码。
实操中,建议为每个输入点建立数据流清单:输入来源(GET/POST/Header)、处理逻辑(过滤/编码)、输出位置(HTML/属性/JS)。这能帮你快速定位风险点。
实战:手工检测XSS载荷
当你怀疑某个参数存在XSS,可以按以下步骤测试:
- 输入基础载荷
<script>alert(1)</script>,观察是否原样输出。 - 若被过滤,尝试编码变体:
<script>alert(1)</script>(HTML实体)或%3Cscript%3Ealert(1)%3C/script%3E(URL编码)。 - 若标签被过滤,改用事件属性:
<img src=x onerror=alert(1)>或<svg onload=alert(1)>。 - 检查输出位置:如果输入被放在
<a href="...">中,尝试javascript:alert(1)。 - 观察浏览器控制台和网络请求,确认是否执行。
注意:测试时务必在本地或授权环境进行,避免对线上造成影响。若遇到WAF拦截,可尝试大小写混合、注释符(如 <scr<script>ipt>)等绕过技巧,但需结合具体过滤规则。
利用Cloudflare缓存与Worker进行防护
云防护能有效缓解XSS攻击。以Cloudflare为例,其缓存和Worker功能可辅助过滤危险请求。
Cloudflare的缓存服务会在边缘节点存储静态资源副本,减少源站压力。你可以在缓存规则中配置对可疑URL的缓存策略,但缓存本身不直接过滤XSS。真正有用的是Cloudflare Workers:你可以编写脚本在边缘检查请求参数,拦截包含危险特征的请求。
例如,一个简单的Worker可以检测URL中是否包含 script 或 onerror,若命中则返回403。但这只是基础防护,且可能误伤合法输入。更稳妥的做法是结合Cloudflare的DDoS防护和WAF规则,它们能自动识别并拦截常见攻击载荷。
自动化检测:编写简单的载荷扫描器
手动测试费时,你可以用脚本自动化检测。以下是一个Python示例(伪代码):
import requests
payloads = [
'<script>alert(1)</script>',
'<img src=x onerror=alert(1)>',
'javascript:alert(1)',
]
for p in payloads:
r = requests.get(f'https://example.com/search?q={p}')
if p in r.text:
print(f'XSS risk: {p}')
这个脚本发送带有载荷的请求,检查响应中是否原样回显。但要注意:有些应用会过滤但输出编码,导致载荷不直接出现,所以这只能作为初步筛查。更深入的分析需要结合DOM解析和浏览器模拟。
识别危险输入特征的最佳实践
结合上述分析,识别危险输入特征时,应关注以下关键点:
- 检查输入是否包含标签起始符:
<和>是HTML注入的基础。 - 警惕事件处理属性:如
onerror、onload、onclick等。 - 检查URL协议:
javascript:、vbscript:等危险协议。 - 注意编码变体:HTML实体、URL编码、Unicode编码都可能绕过过滤。
- 结合上下文判断:同样输入在HTML标签内和属性内风险不同。
在防御端,推荐使用安全响应头(如CSP)作为纵深防御。CSP可以限制脚本来源,即使载荷被注入,也无法执行。这能显著降低XSS危害。
常见误区与失败条件
识别XSS载荷时,容易陷入以下误区:
- 只过滤
script标签:忽视事件属性和协议,导致绕过。 - 依赖黑名单:黑名单难以覆盖所有变体,应结合白名单和输出编码。
- 忽略输出编码:输入过滤重要,但输出编码才是根本防线。
- 过度依赖WAF:WAF可能被绕过,且可能误伤,需结合代码层防护。
失败条件包括:未对输出进行编码、过滤规则不完整、使用了不安全的DOM操作(如 innerHTML)。
参考资料
延伸阅读
