前端网络安全必修课 1:SOP、CSRF 与 CORS

前端网络安全必修课 1:SOP、CSRF 与 CORS

💡 原文日文,约6300字,阅读约需15分钟。
📝

内容提要

本文讲解前端网络安全三大概念:同源策略限制跨源读取响应而非发送请求,无法防CSRF;CSRF利用Cookie自动携带发起恶意请求,可用Token认证防御;CORS通过服务器响应头实现跨源共享,分简单请求与预检请求,预检可防CSRF,跨源携带Cookie需前后端同时配置。

🔎

延伸解读

同源策略:限制读取而非发送

同源策略(SOP)常被误解为禁止跨源请求,实则它只拦截跨源响应的读取。浏览器允许通过<img>、<form>等标签发送跨源请求,但JavaScript无法获取响应内容。这种设计在保护用户数据的同时,也留下了CSRF攻击的隐患,因为攻击者无需读取响应,只需触发请求即可。

CSRF防御:Token认证为何有效

CSRF利用浏览器自动携带Cookie的机制,冒充用户发起请求。防御的关键是打破这种自动性:使用Token认证,将Token存储在非Cookie位置(如localStorage),并在请求头中手动添加。由于同源策略限制,攻击者无法读取Token,因此无法伪造合法请求。

CORS预检请求:意外的CSRF防线

CORS将请求分为简单请求和预检请求。简单请求直接发送,可能被CSRF利用;而预检请求要求浏览器先发送OPTIONS请求验证权限,通过后才发送实际请求。由于预检请求需要服务器明确许可,攻击者难以伪造,因此预检请求间接提供了CSRF防护。

跨源携带Cookie:前后端需协同配置

默认情况下,跨源CORS请求不会携带Cookie。若需携带,前端需设置withCredentials为true,后端需设置Access-Control-Allow-Credentials为true,且Access-Control-Allow-Origin不能为通配符*,必须指定具体源。这种双重配置确保了安全性,但也增加了开发复杂度。

❓

Q&A

同源策略(SOP)到底限制了什么?

同源策略并不禁止跨源请求的发送,而是拦截跨源请求的响应。具体来说,对于iframe、图片等资源,可以正常引用,但无法操作其内容;对于Ajax请求,请求会发送到服务器,但浏览器会阻止JavaScript读取响应结果。

为什么同源策略不能防御CSRF攻击?

因为同源策略只拦截响应,不阻止请求发送。CSRF攻击利用HTML标签(如img、form)发起跨源请求,这些请求会正常发送并自动携带Cookie,服务器会执行相应操作,而攻击者无需读取响应。因此同源策略无法防御CSRF。

CSRF攻击是如何实现的?

CSRF(跨站请求伪造)发生在用户已登录A网站并保存Cookie后,攻击者诱导用户访问恶意B网站,B网站通过img标签发起GET请求或通过form表单发起POST请求调用A网站的API。由于浏览器会自动携带A网站的Cookie,A网站误以为是用户本人操作,从而执行恶意请求。

有哪些有效防御CSRF的方法?

主要方法有两种:一是使用Token认证,将Token存储在非Cookie位置(如localStorage),并在请求头中手动添加,服务器验证Token;二是将Cookie中的值提取出来,在请求时作为查询参数、请求体或自定义请求头发送,服务器只校验该值而不依赖Cookie。此外,CORS预检请求也能阻止部分CSRF。

CORS中的简单请求和预检请求有什么区别?

简单请求使用GET、POST或HEAD方法,且Content-Type为application/x-www-form-urlencoded、multipart/form-data或text/plain,直接发送并可能引发CSRF。预检请求针对不满足简单请求条件的请求(如PUT方法或application/json),浏览器先发送OPTIONS请求询问服务器是否允许跨源,验证通过后才发送实际请求,因此能防御CSRF。

跨源CORS请求如何携带Cookie?

默认情况下,跨源CORS请求不会发送Cookie或HTTP认证信息。需要前端设置withCredentials为true(如axios中),同时后端设置Access-Control-Allow-Credentials为true。注意,此时Access-Control-Allow-Origin不能为*,必须指定具体源。

🏷️

标签

➡️

继续阅读