微信登录

安全考虑 - 防止 CSRF 攻击 - 跨站请求伪造防护

Node.js 安全考虑 - 防止 CSRF 攻击 - 跨站请求伪造防护

什么是 CSRF 攻击

跨站请求伪造(Cross - Site Request Forgery,简称 CSRF)是一种常见的 Web 安全漏洞,攻击者通过诱导用户在已登录的受信任网站上执行非预期的操作。攻击者利用用户在浏览器中的会话信息,在用户不知情的情况下向目标网站发送恶意请求,由于浏览器会自动携带该网站的 cookie 等认证信息,服务器会将这些请求视为合法用户的操作,从而导致安全问题。

示例场景

假设用户 Alice 已经登录了她的网上银行账户。攻击者 Bob 诱导 Alice 访问一个恶意网站,该网站包含一个隐藏的表单,表单的 action 指向 Alice 银行账户的转账接口。当 Alice 访问这个恶意网站时,浏览器会自动携带银行网站的 cookie 信息发送转账请求,银行服务器会认为这是 Alice 的合法操作,从而完成转账。

在 Node.js 中防止 CSRF 攻击

使用 CSRF 令牌

CSRF 令牌是一种常用的防止 CSRF 攻击的方法。服务器在生成页面时会为每个用户会话生成一个唯一的 CSRF 令牌,并将其包含在页面的表单或请求头中。当用户提交请求时,服务器会验证请求中携带的 CSRF 令牌是否与服务器端存储的令牌一致。如果不一致,则拒绝该请求。

演示代码

以下是一个使用 Express 框架和 csurf 中间件实现 CSRF 防护的示例:

  1. const express = require('express');
  2. const session = require('express-session');
  3. const csrf = require('csurf');
  4. const bodyParser = require('body-parser');
  5. const app = express();
  6. // 配置会话
  7. app.use(session({
  8. secret: 'your-secret-key',
  9. resave: false,
  10. saveUninitialized: true
  11. }));
  12. // 解析表单数据
  13. app.use(bodyParser.urlencoded({ extended: false }));
  14. // 启用 CSRF 保护
  15. const csrfProtection = csrf({ cookie: true });
  16. // 获取表单页面
  17. app.get('/form', csrfProtection, (req, res) => {
  18. // 将 CSRF 令牌传递给表单页面
  19. res.send(`
  20. <form action="/submit" method="post">
  21. <input type="hidden" name="_csrf" value="${req.csrfToken()}">
  22. <input type="text" name="message" placeholder="Enter a message">
  23. <input type="submit" value="Submit">
  24. </form>
  25. `);
  26. });
  27. // 处理表单提交
  28. app.post('/submit', csrfProtection, (req, res) => {
  29. const message = req.body.message;
  30. res.send(`You submitted: ${message}`);
  31. });
  32. const port = 3000;
  33. app.listen(port, () => {
  34. console.log(`Server is running on port ${port}`);
  35. });

代码解释

  1. 会话配置:使用 express - session 中间件来管理用户会话,为每个用户分配一个唯一的会话 ID。
  2. 表单数据解析:使用 body - parser 中间件来解析表单数据。
  3. CSRF 保护:使用 csurf 中间件启用 CSRF 保护。csrfProtection 是一个中间件函数,用于生成和验证 CSRF 令牌。
  4. 获取表单页面:在 /form 路由中,使用 csrfProtection 中间件生成 CSRF 令牌,并将其包含在表单的隐藏字段中。
  5. 处理表单提交:在 /submit 路由中,同样使用 csrfProtection 中间件来验证请求中携带的 CSRF 令牌。如果令牌验证通过,则处理表单数据;否则,会抛出 CSRF 错误。

总结

防护方法 原理 优点 缺点
CSRF 令牌 服务器生成唯一令牌,包含在表单或请求头中,请求时验证 实现相对简单,能有效防止 CSRF 攻击 需要在每个表单或请求中包含令牌,增加开发复杂度

通过在 Node.js 应用中使用 CSRF 令牌,我们可以有效地防止跨站请求伪造攻击,保护用户的信息安全。在实际开发中,建议始终启用 CSRF 保护,确保应用的安全性。

安全考虑 - 防止 CSRF 攻击 - 跨站请求伪造防护