XSS(Cross-Site Scripting,跨站脚本)是一类漏洞:网站把用户输入当成代码,直接送进别人的浏览器执行。缩写不是 CSS,因为层叠样式表(CSS)已经占了这个名字,只好写成 XSS。
浏览器分不清"内容"和"代码"
一个网页本质上是文本,浏览器负责解释它:<h1> 是标题,<script> 是要执行的程序。麻烦在于,页面里往往还要嵌入用户自己的东西——评论、昵称、搜索关键词。
如果网站把这些输入原样拼进 HTML,浏览器并不会区分"这是站长写的"还是"某个访客填的"。它只看到一个 <script> 标签,然后照常执行。
打个比方:公司大厅的公告栏。公告栏本来贴的是公司通知,但如果你允许任何人往上贴纸条,那么一张写着"请把门禁卡交给拿这张纸条的人"的纸条,看起来和正式通知没两样。公告栏不判断真假,它只负责展示。
攻击链条长什么样
1. 攻击者在评论框、昵称或搜索框里填一段脚本;
2. 网站没做转义,把它存进数据库,或直接回显到页面上;
3. 其他用户打开这个页面,浏览器把它当代码执行;
4. 代码以"当前登录用户"的身份运行——能改页面、读页面数据、替用户发请求。
按来源和是否落库,通常分为存储型(Stored)、反射型(Reflected)和 DOM 型(DOM-based)几类,区别只在于坏字符串从哪来、什么时候被执行。
关键点在于:这段代码跑在受害者的浏览器里、跑在受害者已登录的会话里,所以同源策略(Same-Origin Policy)拦不住它——它本来就是"自己人"。
和几个近亲的区别
| 概念 | 代码在哪里执行 | 攻击者图什么 |
|---|---|---|
| XSS | 受害者的浏览器 | 以受害者身份操作页面、读页面数据 |
| SQL 注入 | 数据库服务器 | 数据库里的数据 |
| CSRF(跨站请求伪造) | 不注入代码,借浏览器自动带凭证的机制 | 让用户在不知情下发出请求 |
三者共同的病根都是"把数据当成了指令"。CSRF 不需要往页面里塞代码,它靠的是浏览器会自动带上 Cookie 这个特性。
对从业者和普通人的意义
开发侧:凡是把用户可控内容拼进 HTML 的地方,都要走转义或白名单过滤。现代前端框架默认把文本当文本渲染,但 innerHTML、v-html、dangerouslySetInnerHTML 这类"我知道我在干什么"的开关仍是高频坑点。带 HttpOnly 标记的 Cookie 能减小损失,内容安全策略(CSP)可以做一层兜底。
普通人:后台系统里"粘贴一段 HTML 就能自定义样式"的功能、把用户上传内容直接渲染出来,都是典型风险面。
AI 从业者对这套逻辑不会陌生——提示注入(AI 词典:Prompt Injection">Prompt Injection)就是它的近亲:用户输入被当成指令执行,和用户输入被当成代码执行,犯的是同一个错误,没有把"数据通道"和"指令通道"分开。理解了 XSS 的转义、白名单、权限隔离思路,也就理解了提示注入为什么难防。
