前端网络安全必修 1 SOP、CSRF 和 CORS

前端网络安全必修 1 SOP、CSRF 和 CORS

💡 原文中文,约4900字,阅读约需12分钟。
📝

内容提要

文章讲解前端安全三大概念:同源策略(SOP)限制非同源资源操作,但不阻止简单请求发送,因此无法防CSRF;CSRF利用浏览器自动携带cookie发起伪造请求,对策是用token鉴权并手动放入请求头;CORS是服务器与浏览器协商机制,简单请求直接发送,非简单请求先发预检,跨域默认不带cookie,需设withCredentials。

🔎

延伸解读

同源策略的边界:为何无法阻止 CSRF

同源策略限制非同源资源的操作,但允许通过 HTML 标签发起简单请求,且不阻止请求发送,仅拦截响应结果。因此,攻击者能利用 img、form 等发起 CSRF 请求,浏览器自动携带 cookie,服务器无法区分来源。这解释了 SOP 不能作为 CSRF 防御手段的根本原因。

CSRF 防御核心:Token 与自定义请求头

由于 SOP 无法阻止请求发送,防御 CSRF 需依赖 token 鉴权。将 token 存放在非 cookie 位置(如 localStorage),并在请求头中手动添加,服务器校验自定义字段而非 cookie。这样,跨域攻击者无法读取 token,也无法伪造请求头,从而有效阻断 CSRF。

CORS 预检机制:非简单请求的额外防护

CORS 将请求分为简单请求和预检请求。简单请求直接发送,可能被 CSRF 利用;非简单请求(如 PUT 或 Content-Type 为 application/json)会先发送 OPTIONS 预检,验证通过才发送正式请求。预检机制成为防范 CSRF 的例外,因为攻击者无法让浏览器自动发送预检请求。

跨域 Cookie 传递:withCredentials 与安全限制

CORS 请求默认不发送 Cookie,需前后端同时设置。前端如 axios 需配置 withCredentials: true,后端需设置 Access-Control-Allow-Credentials: true。此时 Access-Control-Allow-Origin 不能为通配符 *,必须指定具体源,以避免安全风险。这增加了跨域携带 Cookie 的配置复杂度。

❓

Q&A

同源策略(SOP)具体限制了什么?

同源策略限制非同源资源的内容操作,例如不能通过 ajax 获取跨域响应结果,也不能操作 iframe 或 canvas 中的跨域内容。但它允许通过 HTML 标签(如 img、script)引用跨域资源,且不阻止简单请求的发送。

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

因为同源策略不阻止简单请求的发送,只拦截响应结果。攻击者可以利用 HTML 标签(如 img、form)发起跨域请求,浏览器会自动携带 cookie,服务器会执行操作,但攻击者无法读取响应,这正好被 CSRF 利用。

CSRF 攻击是如何实现的?

CSRF 利用浏览器自动携带 cookie 的机制。用户登录 A 网站后,cookie 保存了登录信息。攻击者诱导用户访问恶意网站 B,B 通过 img 标签或表单向 A 网站发起请求,浏览器自动带上 A 的 cookie,从而以用户身份执行操作。

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

主要方法有两种:1. 使用 token 鉴权,不将 token 存放在 cookie 中,请求时手动添加到请求头;2. 在请求中通过 query、body 或 header 携带 cookie 中的信息,服务器只验证自定义字段,不依赖 cookie 本身。

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

简单请求使用 GET、POST 或 HEAD 方法,且 Content-Type 为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain,会直接发送。非简单请求会先发送 OPTIONS 预检请求,服务器验证通过后才发送正式请求。

跨域请求时如何携带 cookie?

跨域 CORS 请求默认不发送 cookie,需要前后端都进行配置。前端例如 axios 需设置 withCredentials: true,后端需设置 Access-Control-Allow-Credentials 为 true,并且 Access-Control-Allow-Origin 不能为 *。

🏷️

标签

➡️

继续阅读