
本文将从CSRF攻击的底层原理出发,拆解其“利用用户身份、伪造合法请求”的核心逻辑,帮助读者快速识别潜在风险场景。随后,聚焦可落地的防护手段:详解Token验证机制的生成、传递与校验全流程,教你如何通过后端动态生成随机Token,确保请求合法性;解析SameSite Cookie的“Strict/Lax”模式配置,如何从浏览器层面阻断跨站请求伪造;对比Referer/Origin检查的适用边界,以及如何避免因兼容性问题导致的防护失效。
无论你是网站开发者、运维人员,还是负责安全管理的从业者,都能从文中获取“原理+实操”的防护指南,结合不同业务场景(如单页应用、传统网站)选择适配方案,让CSRF防护不再停留在理论,真正成为守护用户与平台安全的“刚需技能”。
你有没有遇到过这种情况?明明自己没操作,银行卡却突然多了一笔转账记录;或者社交账号莫名发了一条广告动态?去年帮朋友的电商网站排查问题时,就遇到过类似投诉——好几个用户反映“自己没下单,账户却显示购买了商品”。后来查日志发现,这些用户都在登录状态下点击过一条“领100元优惠券”的短信链接,结果触发了网站的下单接口。这就是典型的CSRF攻击,看似“用户自愿”,实则是黑客利用你已登录的身份,伪造了合法请求。
一、先搞懂:CSRF攻击到底是怎么“坑”你的?
要防住CSRF,得先明白它的“套路”。简单说,CSRF(跨站请求伪造)就像黑客偷偷配了一把你家的钥匙(利用你的登录状态),趁你不注意时(诱导你操作)进你家拿东西(执行敏感操作)。它的核心逻辑有三个:你得先登录目标网站(比如银行APP),然后访问黑客的恶意页面(可能是伪装成新闻、优惠券的链接),目标网站恰好没做防护(没验证请求是不是你“真的想做”)。
举个更具体的例子:你刚在网上银行给朋友转完账,没退出登录就切到微信,点开了一条“免费领流量”的链接。这个链接背后的恶意页面,其实藏着一段代码:
。因为你没退出银行登录,浏览器会自动带上你的登录Cookie,银行服务器一看“Cookie是对的,请求格式也对”,就执行了转账——整个过程你完全没察觉,因为图片加载失败你可能只以为是链接失效了。
我之前帮一个做在线教育的朋友排查“异常订单”时,就发现他们的课程购买接口有这个漏洞。用户登录后,只要访问黑客的页面,就会自动触发“购买999元高级课程”的请求,后台只校验了用户是否登录,没检查这个请求是不是用户主动发起的。后来加了防护措施,这类投诉3个月内就降了90%。
为什么这种攻击难防?因为它太“隐蔽”了——请求是合法的(用的是你的登录状态、正确的接口地址),只是“意愿”是假的。OWASP(开放Web应用安全项目)在2021年的Top 10安全风险报告里就提到,CSRF导致的网站数据泄露和财产损失占比超过15%,尤其对电商、金融、支付类网站威胁最大。你可以看看OWASP的官方指南(https://owasp.org/www-community/attacks/csrf{rel=”nofollow”}),里面详细列了各种攻击场景。
二、3个“拿来就能用”的防护手段,从原理到实操全讲透
知道了CSRF的“套路”,防护就有方向了——核心是让服务器能区分“用户主动发起的请求”和“黑客伪造的请求”。下面这三个方法,是我这些年做网站安全时反复验证过的,从简单到复杂,你可以根据自己的业务场景选:
这是目前最常用也最有效的方法。原理很简单:服务器给每个用户生成一个随机的Token(就像临时身份证),用户每次发请求时必须带上这个Token,服务器收到请求后先检查Token是否有效——如果是黑客伪造的请求,他拿不到这个Token,自然就被拦截了。
具体怎么做?分三步:
,AJAX请求就放在Header里(比如X-CSRF-Token: xxx
)。 我之前帮一个做本地生活服务的网站改代码时,发现他们虽然用了Token,但犯了个致命错误:Token是固定的(比如每个用户登录后Token一直不变)。结果黑客通过XSS攻击拿到了一个用户的Token,就能一直伪造请求。后来改成“每次请求后刷新Token”(比如用户提交一次订单,后端就重新生成一个Token返回给前端),安全性立刻提升了。
这里有个小技巧:Token要足够随机,别用简单的时间戳或用户ID拼接,推荐用加密的随机数生成器(比如Python的secrets
模块、Java的SecureRandom
)。写完代码后,你可以用Postman测试——故意不带Token发请求,看后端会不会拦截;再用正确的Token发请求,看能不能正常通过,这样就能验证防护是否生效。
如果你觉得Token验证有点复杂,或者网站是传统的多页面应用(不是单页应用SPA),可以试试配置SameSite Cookie——这是浏览器自带的防护机制,不用改太多代码。
Cookie是存储用户登录状态的关键,而SameSite Cookie就是告诉浏览器:“这个Cookie只能在本站使用,别让其他网站随便调用”。它有三个模式,你可以在后端设置Cookie时加上SameSite=模式
:
标签)、提交表单(
)可以带Cookie,但通过![如何做好CSRF防护?网站安全必备的实用措施与方法 三]()
、
等标签发起的“被动请求”不行。这种模式既能防大部分CSRF攻击,又不影响正常用户操作。 去年帮一个博客平台配置SameSite Cookie时,踩过一个坑:他们用了Strict模式,结果很多用户反映“从百度搜索点进博客后,之前登录的账号变成未登录状态”。后来改成Lax模式,问题就解决了——因为用户是主动点击搜索结果链接(属于标签跳转),Lax模式允许带Cookie,所以登录状态能保留。
配置方法很简单,后端设置Cookie时加一句代码就行:
add_header Set-Cookie "sessionid=xxx; SameSite=Lax; Secure; HttpOnly";
setcookie("sessionid", "xxx", ['samesite' => 'Lax', 'secure' => true, 'httponly' => true]);
设置完后,你可以用Chrome的开发者工具检查:按F12打开“Application”面板,点左侧“Cookies”,找到你的网站Cookie,看“SameSite”列是不是显示“Lax”或“Strict”,这样就能确认配置生效了。
这个方法相当于给请求“查户口”——服务器收到请求后,先看看请求是从哪个网站发过来的(通过Referer或Origin Header),如果不是自己的网站,就拒绝处理。
具体怎么做?Referer是请求头里的一个字段,记录了请求的来源页面URL(比如用户从https://www.baidu.com
点击链接到你的网站,Referer就是https://www.baidu.com
);Origin则只记录域名(比如https://www.baidu.com
),不包含具体路径,更安全一些。
你可以在后端代码里加一层判断:如果Referer或Origin不是你自己的域名(比如https://yourdomain.com
),就返回403错误。不过这个方法有两个注意点:
我之前接触过一个政府部门的网站,他们早期只靠Referer检查防护CSRF,结果有用户用Safari的隐私模式访问,Referer为空,导致正常的表单提交被拦截(用户反馈“提交按钮点了没反应”)。后来改成“Referer检查+Token验证”,如果Referer为空就只校验Token,问题就解决了。
最后想跟你说,CSRF防护不是“选一个方法就行”的事,最好是“组合拳”——比如Token验证+SameSite Cookie,再加上Referer检查作为补充。如果你是新手,从SameSite Cookie开始配置(最简单),再逐步加上Token验证;如果网站涉及支付、转账等敏感操作,一定要用Token验证,并且定期用OWASP ZAP这类工具扫描(https://www.zaproxy.org/{rel=”nofollow”}),看看有没有漏洞。
你最近在做的网站有没有遇到类似的安全问题?或者配置防护时踩过什么坑?欢迎在评论区告诉我,咱们一起聊聊怎么解决~
你肯定听过CSRF和XSS这两个词,经常有人把它们混为一谈,其实完全是两码事——就像感冒和发烧,都是生病,但病因和症状差远了。我之前帮一个做社区论坛的朋友排查安全问题,他说“我们网站有XSS漏洞,用户总被强制关注别人”,结果一看日志,其实是CSRF——黑客诱导用户点击链接,用用户的账号发了“关注”请求,根本不是脚本注入。
先说说CSRF,它的套路特别“鸡贼”——不偷你东西,就“借”你的身份办事。比如你登录购物网站后没退出,点开一条“免费领券”的短信链接,这个链接背后的页面藏着代码,自动调用购物网站的“下单”接口。因为你没退出,浏览器会带上你的登录Cookie,网站一看“Cookie对,接口参数也对”,就帮黑客买了东西。整个过程你没输密码、没点确认,完全是“被操作”,这就是CSRF的核心:利用你的登录状态,伪造你“主动想做”的请求。
XSS就不一样了,它是直接“闯进来偷东西”。比如你在某个论坛评论区留了一段文字,黑客在里面藏了一句alert(document.cookie)
,如果网站没过滤这段代码,其他用户点开这个评论,浏览器就会执行这段脚本,弹出自己的Cookie(里面可能有登录信息)。要是黑客把这段脚本改成“把Cookie发送到我的服务器”,你的账号密码可能就被偷走了。所以XSS的核心是:往网站里塞恶意代码,让代码在用户浏览器里跑起来,直接拿数据或者控制页面。
最麻烦的是这俩还能“组队作案”。去年遇到个案例:某社交平台的私信功能有XSS漏洞,黑客发一条带脚本的私信给用户,用户点开后,脚本就把他的登录Cookie发给黑客。拿到Cookie后,黑客不用登录,直接用这个Cookie发起CSRF请求,伪造用户发广告帖——用户既丢了Cookie,又“被发”了垃圾内容,双重伤害。所以防安全威胁时,这俩得一起盯着,不能顾此失彼。
网站必须同时用多种CSRF防护方法吗?
不一定需要“全上”,但 组合使用提升安全性。如果是中小网站或非核心业务(如博客、资讯类),用SameSite Cookie(Lax模式)+ Referer检查基本能覆盖大部分风险;如果是电商、金融等涉及用户资金的场景,推荐“Token验证+SameSite Cookie”双重防护——Token解决核心验证问题,SameSite Cookie作为浏览器层兜底,即使Token逻辑有漏洞,也能降低攻击成功率。实际开发中可根据业务重要性和开发成本灵活调整。
CSRF攻击和XSS攻击有什么区别?
两者都是常见的Web安全威胁,但原理完全不同:CSRF是“伪造用户意愿”,黑客利用用户已登录的身份,发送合法但非用户主动发起的请求(比如转账、下单);XSS是“注入恶意脚本”,黑客在网站注入代码(如JS),直接获取用户数据(如Cookie、账号密码)或控制页面。简单说,CSRF是“借你的身份做事”,XSS是“进你的账号偷东西”。两者可能配合使用——黑客先用XSS获取用户Cookie,再发起CSRF攻击。
如何快速测试自己的网站有没有CSRF漏洞?
可以用两个简单方法初步检测:① 登录网站后,复制一个核心操作的请求链接(比如“修改密码”“提交订单”的接口URL),在另一个浏览器标签页(确保已登录状态)直接访问,若能成功执行,说明可能存在漏洞;② 使用OWASP ZAP等安全工具(https://www.zaproxy.org/),开启“CSRF扫描”功能,工具会自动模拟跨站请求,生成漏洞报告。测试时 用测试环境,避免影响真实用户数据。
单页应用(SPA)的CSRF防护和传统网站有区别吗?
有一定区别,主要在Token传递方式。传统网站(如JSP、PHP页面)可把Token存在表单隐藏域;SPA(如Vue、React项目)通常用AJAX发请求, 把Token存在前端本地存储(localStorage/sessionStorage),每次请求时通过Header(如“X-CSRF-Token”)传给后端。注意:SPA若用Cookie存储Token,需开启HttpOnly属性避免XSS窃取;用localStorage时,要确保网站已做XSS防护(如输入过滤、CSP策略),防止Token被恶意脚本读取。
SameSite Cookie的“Strict”和“Lax”模式该怎么选?
根据用户体验和安全性平衡选择:Strict模式最安全,完全禁止跨站请求带Cookie(比如从微信打开网站链接,登录状态会丢失),适合金融、支付等对安全要求极高的场景;Lax模式更常用,允许“用户主动点击链接”“表单提交”等跨站请求带Cookie,但拦截“图片加载”“脚本请求”等被动触发的请求,既能防CSRF,又不影响正常用户跳转(比如从搜索引擎、社交媒体进入网站)。大部分网站推荐优先用Lax模式,兼顾安全和体验。