你的网站是怎么被偷数据、被借账户的?一文讲透 XSS 和 CSRF
|
admin
2026年10月30日 21:2
本文热度 166
|
最近韩新韩银行约 2.5 万客户数据被盗,回想自己的网站被偷数据、账号被拿去买单发帖,是种什么体验。这两种最常见的 Web 攻击,XSS 和 CSRF,很多前端只听过名字,不知道它们到底怎么运作、又怎么防。今天把这两条攻击链拆开,从原理讲到防御。
一条偷数据,一条借账户,尽头都是用户的信任
01 先看 XSS:脚本是怎么混进你页面的
XSS 全称 Cross-Site Scripting,跨站脚本攻击。它不是去黑你的服务器,而是往你的页面里塞一段能执行的 JS,让它在访问者的浏览器里替你干坏事。最常见的入口是输入框。一个用户提交了这段伪装的评论内容,stealCookie(),如果你的页面把它原样当 HTML 插进去,这段代码就会在每一个打开这条评论的访客浏览器里执行,把你的 Cookie 发到攻击者的服务器。用户以为填的是普通文字,代码把它当成了活脚本。// 危险:把用户输入原样当 HTML 插进 DOM commentBox.innerHTML = userInput // 用户输入 "<script>...</script>" 会真的执行
XSS 有三副面孔,共同点都是用户输入被当成了代码。反弹型,恶意脚本藏在一个链接里,点击才触发,骗你访问一个带参数的 URL。存储型最狠,脚本被存进服务器数据库,每个访问该页的人都会中招,评论区和论坛是重灾区。还有 DOM 型,脚本直接在前端的 DOM 操作里被拼进页面,服务器全程没察觉。它偷的不只是 Cookie。伪装的表单能套走密码,脚本能改页面内容做钓鱼,甚至能劫持整个会话冒充你操作。我接手过一个论坛项目,评论直接 `innerHTML` 塞进去,被存储型 XSS 整得整个站瘫痪了一下午。02 再看 CSRF:账户是被借出去的
CSRF 全称 Cross-Site Request Forgery,跨站请求伪造。套路和 XSS 正好反过来。它不注入脚本,而是利用你的登录态,在你不知情时,从另一个网站发出一个会被当成你的请求。机制其实很朴素。你登录了银行网站,浏览器存了登录 Cookie。这时候你不小心打开了一个恶意页面,它里面藏着一张图片或者一段表单提交,指向银行的转账接口。浏览器发请求时,会主动带上那个域的 Cookie,服务器一看带凭证,就当真了,钱就这么被转走。 <img src="http://bank.com/api/transfer?to=hacker&amount=9999" />
关键就在这。请求确实是伪造的,可它是从你的浏览器、带着你的凭证发出去的,服务器无法分辨是本人操作还是被借了身份。盗刷资金、冒充你发帖、改你的绑定邮箱,只要接口不够严格,什么都能干。03 它们共用一条底线
永远不要信任用户的提交内容。XSS 是页面把用户的文字当成了代码,CSRF 是接口把带了凭证的请求当成了本人。一个错信了内容,一个错信了身份。如果代码在任何一端多点戒心,两条攻击链都走不到尽头。而防御其实有成熟的套路,前面做转义、用安全 DOM 方法、加 CSP 限制脚本、CSRF 用 token 和 SameSite,就已经挡下了绝大多数攻击。04 前端能挖的几道防御工事
前端能做的防御,从最简单的开始,没几样,但都管用。第一件,输出转义。用户输入一律按纯文本处理,该转的字符转走,别让它有机会变成活 HTML。填用户内容时用 `textContent`,别用 `innerHTML`。`textContent` 只当文字,`innerHTML` 会解析成标签。就这一行的差别,决定了一串文字是安全显示还是变成攻击载荷。// textContent 只显示文字,永远当成数据 commentText.textContent = userInput // 即使 userInput 是 "<script>...</script>" 也只会原样显示
第二件,内容安全策略 CSP。在响应头里声明,页面只允许加载哪些来源的脚本,其他的一律拒绝。就算攻击脚本被塞进去了,CSP 也能拦住它不让执行。
Content-Security-Policy: default-src 'self'; script-src 'self'
第三件,别用 `eval` 这类能执行字符串的 API,也别拼接用户输入当命令。第四件,前端框架里 `v-html`、`dangerouslySetInnerHTML` 这类调用尽量别碰,真要用就自己把内容转义干净再塞进去。至于 CSRF,前端能扛的主力是两点。给状态迁移类接口加可验证的 token,这个 token 放在 Cookie 里,每个请求都要带,攻击者的站点拿不到它。再把 Set-Cookie 加上 `SameSite=Lax`,让跨站来的请求不带 Cookie 或受限,从根上堵住借用凭证这条路。我改过一个被 CSRF 骚扰过的项目,加了两层防御才消停。一层是请求头里校验一个自定义字段,跨域伪造的简单请求根本带不上正确的值,再加一层 SameSite。前端多做这两件事,服务器压力小一半,攻击面也窄一半。5
最后的防线
XSS 偷你的数据,CSRF 借你的账户,两条攻击链都能绕到你面前,却都断在同一个原则,保持怀疑。对用户输入保持怀疑,对请求来源保持怀疑。最后说句当前时态的话。生成式 AI 替人写代码越来越普遍,但 AI 生成的代码,默认是最省事、最常见的写法,恰恰是 `innerHTML`、`dangerouslySetInnerHTML` 这类有风险接口最爱出现的地方。把安全这道烙印刻进代码审查的清单里,比依赖任何工具都靠得住。等 AI 能自己证明零漏洞那天,再把这活交出去。
阅读原文:原文链接
该文章在 2026/10/31 10:17:25 编辑过