Files
2025-09-25 03:22:13 +08:00

53 lines
2.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
### JSON 格式的 CSRF 如何防御
**1. 使用 CSRF Token**
这是最常见和最可靠的防御方法
- **工作原理**
1. 服务器在用户登录后,生成一个随机、唯一的 CSRF Token,并将其存储在**会话中**或**某个安全的地方**(如 `sessionStorage`
2. 服务器将 Token 发送给客户端
3. 客户端在发起任何敏感操作的请求时,都必须将这个 Token 放在**HTTP 请求头**或 **POST 请求体**中
4. 服务器接收到请求后,会验证请求中的 Token 是否与服务器上存储的 Token 相匹配。如果不匹配,则拒绝请求
- **在 JSON 请求中的实践** 客户端的 JavaScript 代码在发起 POST 请求时,将 Token 放在一个自定义的 HTTP 头中,例如 `X-CSRF-TOKEN`
```js
fetch('https://your-api.com/transfer', {
method: 'POST',
body: JSON.stringify({ to: 'attacker', amount: 1000 }),
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': 'your-generated-token'
}
});
```
**防御原理**:攻击者无法从 `your-api.com` 域获取有效的 CSRF Token。由于同源策略的限制,恶意网站的 JavaScript 无法读取你的 API 返回的 HTML 或 JSON 数据,因此无法获取 CSRF Token。此外,即使是简单请求,自定义的 HTTP 头也会触发预检请求,同样会被 CORS 机制拦截
**2. 使用 SameSite Cookie**
前面我们讨论过 `SameSite` 属性。在 JSON API 的场景中,`SameSite=Lax` 同样是有效的防御
- **工作原理** 将你的会话 Cookie 的 `SameSite` 属性设置为 `Lax` 或 `Strict`。当攻击者从恶意网站发起 POST 请求时,浏览器不会携带这个会话 Cookie。服务器在验证请求时,因为没有会话信息,会直接拒绝请求
```
Set-Cookie: sessionid=xxxx; SameSite=Lax; Secure; HttpOnly
```
- **最佳实践**
- `SameSite=Strict`:提供了最强的防御,但可能影响用户体验
- `SameSite=Lax`:在大多数情况下提供了足够的保护,同时不影响用户从其他网站通过 GET 链接跳转到你的网站
**3. 验证 Referer 或 Origin 头**
这种方法是辅助性的,但可以提供额外的安全层
- **工作原理**: 服务器检查请求头中的 `Referer` 或 `Origin` 字段,验证请求的来源是否为你的合法域名
- `Referer`:表示发起请求的 URL
- `Origin`:表示请求的来源域,通常用于 CORS 预检请求中
- **局限性**
- `Referer` 字段可以被一些浏览器或代理软件修改或删除
- 这不是一个完全可靠的防御方法,应作为辅助手段而非主要策略