当前位置: 首页 > news >正文

同源策略 ≠ 万能盾牌:为什么你的后端仍需防范“盲打“攻击?

一个常见的认知误区:很多开发者认为浏览器的同源策略(Same-Origin Policy)已经阻止了跨域攻击,因此忽略了后端对请求来源的校验。然而事实残酷——同源策略只管"读",不管"写"。恶意网站完全可以在你不知情的情况下,用你的身份执行转账、删号等高危操作。

一、同源策略的"盲区":它只管数据泄露,不管数据篡改

当我们谈到浏览器安全时,同源策略(SOP)总是被首先提及。它确实有效地防止了以下场景:

javascript

// 你在 a.com 登录了银行 // a.com 的 JS 试图读取 b.com 的数据 fetch('https://b.com/api/balance') .then(res => res.json()) .then(data => console.log(data)); // ❌ 被浏览器拦截:CORS policy blocked

但是,如果我们换个写法——不关心服务器返回什么,只让服务器执行操作:

javascript

// 恶意网站 evil.com 的代码 fetch('https://bank.com/transfer?to=hacker&amount=10000', { method: 'POST', // 甚至不需要处理响应... });

会发生什么?

  1. ✅ 请求确实发出去了(带上了你的 Cookie)
  2. ✅ 银行服务器已经执行了转账(钱没了)
  3. ✅ 响应也回到了浏览器(你可以在 DevTools 里看到 200 OK)
  4. JS 拿不到响应数据(同源策略只拦住了这一步)

这就是CSRF(跨站请求伪造)攻击的核心:恶意网站不需要知道你的余额,它只需要让你的浏览器去执行操作

二、CSRF 攻击实战模拟

想象这样一个场景:

上午 9:00:你在银行网站 bank.com 登录,浏览器保存了 Session Cookie。

上午 10:00:你没关浏览器,打开了钓鱼邮件里的链接 evil.com。

evil.com 的 HTML(极其简单,甚至不需要 JS):

html

<body> <h1>精美壁纸下载中...</h1> <!-- 图片自动加载,触发 GET 请求 --> <img src="https://bank.com/transfer?to=attacker&amount=50000" width="0" height="0" /> <!-- 或者自动提交的表单 --> <form id="csrf" action="https://bank.com/change-email" method="POST"> <input type="hidden" name="email" value="hacker@evil.com" /> </form> <script>document.getElementById('csrf').submit();</script> </body>

结果:你的银行卡转账 5 万元,或者绑定邮箱被改成了黑客的。整个过程不需要 JavaScript 读取任何返回数据,同源策略对此完全无能为力

三、后端校验:守护最后一道防线

既然浏览器"靠不住",服务端必须承担校验责任。目前业界主流的防御方案有三层:

1. CSRF Token(最经典可靠)

原理:在表单或请求头中嵌入一个随机生成的、只有服务器和当前页面知道的 Token。

html

<!-- 银行页面渲染时生成随机 Token --> <form action="/transfer" method="POST"> <input type="hidden" name="csrf_token" value="dW5pcXVlLWhhc2gtdmFsdWU=" /> <input name="amount" value="1000" /> <button>转账</button> </form>

java

// Spring Boot 示例 @PostMapping("/transfer") public String transfer(@RequestParam String amount, @RequestParam String csrf_token, HttpSession session) { // 校验 Token 是否与会存中存储的一致 if (!csrf_token.equals(session.getAttribute("csrf_token"))) { throw new SecurityException("疑似 CSRF 攻击!"); } // 执行转账... }

关键:恶意网站 evil.com无法读取bank.com 的页面内容(同源策略这时候起作用了!),因此拿不到 Token,请求自然被后端拒绝。

2. SameSite Cookie(现代浏览器的防线)

通过设置 Cookie 属性,让浏览器不在跨域请求中携带敏感 Cookie:

http

Set-Cookie: sessionId=abc123; SameSite=Strict; HttpOnly; Secure

  • SameSite=Strict:完全禁止第三方 Cookie(最安全,但可能影响从微信/邮件点击链接的体验)
  • SameSite=Lax:允许顶级导航(如 <a> 标签跳转)携带 Cookie,但阻止 POST/PUT 等危险操作(推荐折中方案)

3. Origin/Referer 校验(请求来源验证)

检查 HTTP Header 中的来源信息:

java

@PostMapping("/sensitive") public ResponseEntity<?> sensitiveOperation(@RequestHeader("Origin") String origin) { if (!"https://bank.com".equals(origin)) { return ResponseEntity.status(403).body("非法来源"); } // 继续处理... }

注意:Referer 可以被抹除(HTTPS 跳 HTTP 时不带),所以优先校验 Origin 头,同时不能作为唯一防线

四、总结:两道门的安全哲学

理解同源策略和 CSRF 防护的关系,可以用一个比喻:

同源策略阅览室的保安:防止外人偷看你的文件(保护数据隐私)。CSRF 防护金库的指纹锁:确保操作者真的是你本人(保护操作安全)。

两者缺一不可

  • 没有同源策略,坏人能直接读取你的敏感信息(余额、 Token)。
  • 没有 CSRF 防护,坏人能盲打执行高危操作(转账、改密),即使你收不到回执。

给开发者的建议

  1. 高风险操作(资金、隐私修改)必须实施 CSRF Token 验证,不能仅靠前端校验。
  2. 逐步淘汰纯 Cookie 鉴权,采用 Authorization: Bearer Token 方案(Token 不自动携带,需 JS 显式写入 Header,天然防 CSRF)。
  3. 开启 SameSite=Lax,作为兜底防护。

同源策略解决了"谁能看到"的问题,但"谁能操作"必须由你的后端来回答。别让浏览器的"好意"成为安全架构的盲点。

http://www.jsqmd.com/news/318852/

相关文章:

  • 【AI】在RK3576上,使用RKNN实现MeloTTS(文本转语音)
  • C++与Python混合编程实战
  • 高性能序列化库
  • 8个常见错误及避免方法,优化YashanDB数据库使用
  • C++中的代理模式实战
  • 《Ionic Tab(选项卡)详解与使用指南》
  • 调试技巧与核心转储分析
  • 高性能计算缓存优化
  • 基于Springboot图书借阅管理系统【附源码+文档】
  • 星图平台快速搭建 Clawdbot:私有化本地 Qwen3-VL:30B 并接入飞书平台(下篇)
  • 基于Springboot+HTML5的图书管理系统【附源码+文档】
  • R CSV 文件处理指南
  • 8个策略打造高效YashanDB数据库运维团队
  • 模板编译期条件分支
  • WPF MVVM模式下绑定两个ViewModel导致View不触发更新
  • 高校院所科技成果转化的生态协同之道,数智平台引领产业与学术双赢
  • 【委托监控】【成交监控】
  • C++中的事件驱动编程
  • 晶圆级封装生产线封装装置多轴运动控制系统研究
  • 行为型模式:状态模式——嵌入式状态管理的优雅解决方案
  • 生态协同机制赋能高校成果转化,实现学术产业双赢
  • 提示工程架构师的「提示即代码」实践:3个DevOps案例,AI辅助开发效率提升200%
  • python基于微信的酒店餐饮点菜点餐小程序
  • 泛型编程与STL设计思想
  • 基于Jerk值限制的三阶匀加减速运动轨迹设计
  • Python异步编程入门:Asyncio库的使用
  • Python装饰器详解:让代码更优雅的魔法
  • Claude Code与OpenCode深度对比及使用指南
  • 高校院所科技成果转化数智服务平台:构建产学研协同新生态
  • 用Pandas处理时间序列数据(Time Series)