# 1 代码注入XSS
⚡ 30 秒速记
XSS= 攻击者的脚本混进你的页面,在别的用户浏览器里以你网站的身份执行- 三类:存储型(进了数据库,所有看到的人中招)、反射型(藏在
URL里,靠诱导点击)、DOM型(纯前端拼接,服务端日志里看不到) - 根本防线是按输出位置编码,不是输入过滤;
HTML、属性、JS、URL的转义规则各不一样 - 富文本走白名单净化(
DOMPurify/js-xss),服务端必须再做一次 - 兜底:
HttpOnly让脚本偷不走会话cookie,CSP限制脚本来源
XSS 就是别人的代码在你的页面里跑起来了,而且用的是受害用户的身份。 打个比方,评论区本该显示一段文字,结果浏览器把它当成了 <script> 执行,那这段脚本能读页面数据、调接口、改页面,跟你自己写的代码权限一样。按载荷从哪来分成存储型、反射型和 DOM 型,其中存储型影响面最大。防的思路是让数据永远只当数据:输出时按位置转义,React 的 {} 和 Vue 的 {<span class="vp-brace-split" aria-hidden="true"></span>{}<span class="vp-brace-split" aria-hidden="true"></span>} 默认就做了;真要渲染 HTML 就先白名单净化,再加 CSP 和 HttpOnly 兜底。
跨网站指令码(英语:
Cross-site scripting,通常简称为:XSS)是一种网站应用程式的安全漏洞攻击,是代码注入的一种。它允许恶意使用者将程式码注入到网页上,其他使用者在观看网页时就会受到影响。这类攻击通常包含了HTML以及使用者端脚本语言
XSS分为三种:反射型,存储型和DOM-based
💬 面试官追问
-
我们用
React,默认会转义,是不是就不用管XSS了?不是。
dangerouslySetInnerHTML、href={userUrl}里的javascript:协议、直接操作ref.current.innerHTML,这几个口子React都不管。链接要校验协议只放http/https,HTML要先过DOMPurify.sanitize()。 -
存储型和
DOM型,线上排查有什么不一样?存储型能在数据库里找到那条恶意内容,删掉加净化就止住了。
DOM型可能完全不过服务端,比如location.hash被前端塞进innerHTML,服务端日志里什么都没有,得在前端代码里搜危险sink。 -
前端输入框已经过滤了
<script>,还会被打吗?会。攻击者可以直接调接口绕过前端,也可以用
<img src=x onerror=alert(1)>这种不带script的写法。前端过滤只是体验,防线在输出编码和服务端净化。 -
XSS拿到页面权限后,最坏能干什么?读页面上的数据和
CSRF Token,以用户身份调任意同源接口,比如改绑手机、转账;还能伪造登录框钓密码。所以HttpOnly只能防「偷cookie带走」,防不了「就地操作」。 -
CSP上了script-src 'self',还要做转义吗?要。
CSP是兜底,老浏览器支持不全,配置里一个'unsafe-inline'就前功尽弃,而且它管不了HTML注入改页面结构这类问题。转义是修根因,CSP是降损失。