浅谈CSRF攻击

87 阅读2分钟

1.CSRF攻击原理

  1. 用户登录受信任网站:用户在受信任的网站上登录,并获得一个会话 Cookie
  2. 攻击者诱导用户访问恶意网站:攻击者通过各种手段(如钓鱼邮件、恶意广告等)诱导用户访问一个恶意网站。
  3. 恶意网站发送伪造请求:恶意网站在用户不知情的情况下,向受信任的网站发送伪造的请求。这些请求会携带用户的会话 Cookie,从而使受信任的网站认为这些请求是合法用户发出的。
  4. 受信任网站执行请求:受信任的网站接收到伪造的请求后,认为是合法用户发出的,从而执行相应的操作(如转账、修改密码等)。

2.防御 CSRF 攻击的方法

  1. 使用 CSRF Token:在每个表单或请求中加入一个随机生成的 CSRF Token,并在服务器端进行验证。只有携带正确 Token 的请求才会被执行。

html表单

<form method="POST" action="/transfer">
    //关键代码
    <input type="hidden" name="csrf_token" value="{{ csrf_token }}">
    <input type="text" name="amount" placeholder="Amount">
    <button type="submit">Transfer</button>
</form>

服务器端验证(Node.js 示例)

const express = require('express');
const csrf = require('csurf');
const bodyParser = require('body-parser');

const app = express();
const csrfProtection = csrf({ cookie: true });

app.use(bodyParser.urlencoded({ extended: false }));
app.use(csrfProtection);

app.get('/transfer', (req, res) => {
    res.render('transfer', { csrf_token: req.csrfToken() });
});

app.post('/transfer', (req, res) => {
    // 验证 CSRF Token
    if (req.body.csrf_token !== req.csrfToken()) {
        return res.status(403).send('Invalid CSRF Token');
    }
    // 处理转账逻辑
    res.send('Transfer successful');
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});
  1. 验证 Referer 或 Origin 头:在服务器端检查请求的 Referer 或 Origin 头,确保请求是从受信任的源发出的。
  2. SameSite Cookie 属性:设置 Cookie 的 SameSite 属性为 Strict 或 Lax限制第三方网站发送的请求携带 Cookie
  3. 双重提交 Cookie:在请求中同时提交 Cookie 和表单字段中的 Token,服务器端验证两者是否一致。
  4. 使用 CAPTCHA:在关键操作前使用 CAPTCHA 验证,确保请求是由用户主动发出的。