MST

星途 面试题库

面试题:Next.js API Routes 应对 CSRF 攻击的策略

跨站请求伪造(CSRF)是 Web 应用面临的常见安全威胁之一。在 Next.js 的 API Routes 场景下,请详细描述 CSRF 攻击的原理,以及你所知道的几种防范 CSRF 攻击的策略,并且说明如何在 Next.js 项目中具体实现这些策略。
31.1万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试

CSRF 攻击原理

  1. 攻击场景:用户已登录目标网站 A 并处于认证状态,此时在同一浏览器中访问恶意网站 B。
  2. 恶意操作触发:恶意网站 B 构造一个伪装成网站 A 合法请求的表单或 AJAX 请求,利用浏览器自动携带已登录网站 A 的 Cookie 等认证信息的特性,在用户不知情的情况下,向网站 A 发起请求,执行一些如转账、修改密码等敏感操作。例如,恶意网站 B 中有一段隐藏的表单:
<form action="https://target - site - a.com/transfer" method="post">
    <input type="hidden" name="amount" value="1000" />
    <input type="hidden" name="to" value="attacker_account" />
    <input type="submit" value="Submit" style="display:none" />
</form>
<script>document.forms[0].submit();</script>

当用户访问恶意网站 B 时,该表单会自动提交,由于浏览器会携带用户在目标网站 A 的认证 Cookie,目标网站 A 会认为这是一个合法用户的请求,从而执行转账操作。

防范 CSRF 攻击的策略

1. CSRF Token

  • 原理:在用户访问网站时,服务器生成一个随机且唯一的 Token 并返回给客户端,客户端在每次向服务器发送请求时,将该 Token 包含在请求中。服务器验证请求中的 Token 是否与预期一致,如果不一致则拒绝请求。
  • 在 Next.js 项目中的实现
    • 生成 Token:在服务器端(如 API Routes 中),可以使用 crypto 模块生成 Token。例如:
import crypto from 'crypto';

export default function handler(req, res) {
    const csrfToken = crypto.randomBytes(32).toString('hex');
    res.setHeader('Set - Cookie', `csrfToken=${csrfToken}; HttpOnly; Path=/`);
    res.status(200).json({ csrfToken });
}
- **验证 Token**:在处理敏感请求的 API Routes 中,获取请求中的 Token 并进行验证。
import { NextApiRequest, NextApiResponse } from 'next';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
    const receivedToken = req.cookies.csrfToken;
    const expectedToken = req.body.csrfToken;
    if (receivedToken!== expectedToken) {
        return res.status(403).json({ error: 'CSRF token mismatch' });
    }
    // 处理正常业务逻辑
    res.status(200).json({ message: 'Request processed successfully' });
}

2. Same - Site Cookies

  • 原理:通过设置 Same - Site 属性为 StrictLax 来限制 Cookie 的发送范围。Strict 模式下,只有在同站请求时才会发送 Cookie;Lax 模式下,允许在一些安全的跨站导航(如从外部链接点击进入网站)时发送 Cookie,但对于跨站的 POST 等非安全请求不会发送 Cookie。
  • 在 Next.js 项目中的实现:在设置 Cookie 时添加 Same - Site 属性。例如:
import { NextApiRequest, NextApiResponse } from 'next';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
    res.setHeader('Set - Cookie', `sessionId=12345; Same - Site=Strict; Path=/`);
    res.status(200).json({ message: 'Cookie set' });
}

3. Double Submit Cookie

  • 原理:与 CSRF Token 类似,服务器在设置 Cookie 时,同时将 Token 作为 Cookie 的值。客户端在发送请求时,将该 Cookie 值作为请求头(或请求体)的一部分发送回服务器。服务器验证 Cookie 中的 Token 和请求中的 Token 是否一致。
  • 在 Next.js 项目中的实现
    • 设置 Cookie 与 Token
import crypto from 'crypto';
import { NextApiRequest, NextApiResponse } from 'next';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
    const csrfToken = crypto.randomBytes(32).toString('hex');
    res.setHeader('Set - Cookie', `csrfToken=${csrfToken}; Path=/`);
    res.status(200).json({ csrfToken });
}
- **验证 Token**:
import { NextApiRequest, NextApiResponse } from 'next';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
    const receivedTokenFromCookie = req.cookies.csrfToken;
    const receivedTokenFromRequest = req.headers['x - csrf - token'];
    if (receivedTokenFromCookie!== receivedTokenFromRequest) {
        return res.status(403).json({ error: 'CSRF token mismatch' });
    }
    // 处理正常业务逻辑
    res.status(200).json({ message: 'Request processed successfully' });
}