今天复盘一次近期众测挖到的某 APP 存储型 XSS 漏洞,完整记录从前端限制突破、WAF 规则绕过、事件 FUZZ、字符截断排查到最终拿洞的全过程。文中敏感信息已全部脱敏处理,请勿将技术用于非法用途。
一、突破前端限制
测试目标是某 APP 的个人账户昵称修改功能,属于典型的用户可控输入点,也是存储型 XSS 的高危测试位置。

首次测试发现,前端页面给昵称输入加了字符限制,无法直接发送完整 payload。
突破思路:抓包修改绕过前端校验
所有前端校验本质都是客户端校验,完全可控。页面输入限制只作用于浏览器端,只要抓包拦截修改接口请求数据包,就能绕过所有前端 JS 校验,直接向服务端提交恶意载荷。
初步测试 payload 为 <s>Test</s>。

提交后页面正常解析标签,字体效果也生效了,说明服务端没有过滤 HTML 标签、前端渲染也没有做转义,存在XSS漏洞基础条件。

二、时间戳校验

重放数据包后发现响应提示“修改已经超时”,推测服务端对请求做了时间范围限制。
三、WAF 拦截高危事件
确认标签能够被解析后,继续用常规 hover 触发型 payload <svg onmouseover=1> 测试。
提交后连接被直接拒绝,初步判定:服务端WAF未拦截HTML标签,但是严格拦截常见高危JS事件。

为了验证这个猜想,单独提交纯标签 <svg>,数据包正常回显、没有被拦截。这里“修改超时”提示不影响对 WAF 响应状态的判断。

四、事件大小写绕过
针对事件名做了大小写变形测试,比如 OnMouseOver、ONMOUSEOVER 等,结果全被 WAF 拦住。说明该站点 WAF 对常见高危事件开启了大小写忽略匹配,普通的大小写混淆已经失效,只能去 FUZZ WAF 黑名单没有收录的冷门事件。
五、黑名单 FUZZ

针对 DOM 交互事件做批量 FUZZ,最终筛出一批 WAF 完全放行、又能够正常触发 JS 的冷门事件,这也是这次漏洞利用的关键。
OnMouseEnter
onmouseenter
OnMouseLeave
onmouseleave
OnChange
onchange
OnToggle
ontoggle
这类事件大多属于 HTML5 里比较小众的交互事件,WAF 规则库没有覆盖,自然没有拦截策略,成为本次绕过的核心突破口。
六、进阶绕过
确定可用事件后,选择兼容性最强、触发最稳定的 ontoggle 事件,也就是配合 <details> 标签使用的折叠展开事件,并用大小写混淆标签 <dETAILS>。
初步测试 payload:<dETAILS OnToggle=alert(document.cookie)>

这条 payload 被 WAF 拦截。
换一个思路:利用逗号表达式写法,从根源上抹掉攻击特征。
绕过 payload:<dETAILS OnToggle=a=alert,a(document.cookie)>
这个写法借助 JS 逗号运算符特性,把“函数定义”和“函数调用”拆成两步执行,绕开了 WAF 的特征检测,语法逻辑如下:
第一步:a=alert // 把原生 alert 函数地址赋给自定义变量 a,没有任何高危特征
第二步:a(document.cookie) // 调用自定义变量 a 执行弹窗并读取 Cookie
关键点在于,整个请求报文里不会出现 alert( 这个高危特征串。WAF 看到的只是普通变量 a 的调用,没法通过文本匹配识别恶意行为,于是直接放行。

七、服务端 32 位字符硬截断
回到昵称展示页面,发现折叠标签确实被解析出来了,但并没有弹窗。

站点存在固定 32 字符硬截断机制:超过 32 位的内容会被直接截断丢弃,不会报错,也没有任何提示。

以 payload <dETAILS OnToggle=a=alert,a(document.cookie)> 为例,会被服务端强制截断成:
<dETAILS OnToggle=a=alert,a(docu
JS 语法残缺、表达式不完整,根本无法执行,这也是上一步没有弹窗的根本原因。
既然拿不到 Cookie,就先放弃弹 cookie,改成直接弹窗验证:<dETAILS OnToggle=a=alert,a(1)>


核心优势与绕过原理
- 规避 WAF 对
alert() 的特征拦截:常规 payload 会明文出现 alert(,很容易被 WAF 匹配拦截。本载荷采用逗号表达式先赋值 a=alert,再调用 a(1),原文里没有 alert( 特征,成功绕开函数特征检测。
- 小众事件免拦截:
ontoggle 不是常见高危自动触发事件,WAF 没有默认拦截规则。
最终提交 payload 后,页面正常渲染折叠标签,点击展开后成功弹窗,存储型XSS漏洞验证成功,拿下 300 元众测赏金。
八、漏洞总结与挖洞思路复盘
- 前端限制都能通过抓包绕过,不要被页面上的输入拦截迷惑。
- WAF 大多拦截显性高危特征,小众 HTML5 事件、变量赋值调用语法,都是高效绕过手段。
- 遇到“无报错也不执行”的情况,优先排查服务端字符硬截断,而不是一直纠结 WAF。
- 逗号表达式配合变量调用,是绕过
alert、eval 等高危函数特征的通用高阶 XSS 技巧。
这次漏洞本身难度不高,但非常适合新手学习从踩坑、判断环境、FUZZ 筛选、适配限制到最终利用的完整众测思路,文中所有绕过手法都是实战中可复用的技巧。