如何使用express.js在Ajax调用中实现CSRF保护(寻找完整示例)?

Ben*_*jen 21 ajax csrf connect node.js express

我正在尝试使用express.js框架在使用node.js构建的应用程序中实现CSRF保护.该应用程序充分利用了对服务器的Ajax post调用.我知道connect框架提供了CSRF中间件,但我不确定如何在客户端Ajax post请求的范围内实现它.

在stackoverflow中发布的其他问题中有关于此的一些部分,但我还没有找到一个相当完整的示例,说明如何从客户端和服务器端实现它.

有没有人有一个他们关心如何实现这个的工作示例?我看到的大多数示例都假设您在服务器端呈现表单,然后将其(以及嵌入式csrf_token表单字段)发送到客户端.在我的应用程序中,所有内容都通过Backbone.js在客户端(包括模板)上呈现.所有服务器都提供JSON格式的值,客户端的Backbone.js中的各种模型使用它们.根据我的理解,我需要先使用ajax检索csrf_token才能使用它.但是,我担心从安全角度来看这可能会有问题.这是一个有效的问题吗?

Fiz*_*han 32

可以通过meta为CSRF令牌添加标记然后在每个Ajax请求中传递CSRF令牌来完成

服务器

添加CSRF中间件

app.use(express.csrf());
app.use(function (req, res, next) {
  res.locals.token = req.session._csrf;
  next();
});
Run Code Online (Sandbox Code Playgroud)

您可以通过meta标签将CSRF令牌传递到客户端.对于前,在Jade

meta(name="csrf-token", content="#{token}")
Run Code Online (Sandbox Code Playgroud)

客户

jQuery有一个名为ajaxPrefilter的功能,它允许您提供每个Ajax请求调用的回调.然后使用ajaxPrefilter设置标头.

var CSRF_HEADER = 'X-CSRF-Token';

var setCSRFToken = function (securityToken) {
  jQuery.ajaxPrefilter(function (options, _, xhr) {
    if (!xhr.crossDomain) {
      xhr.setRequestHeader(CSRF_HEADER, securityToken);
    }
  });
};

setCSRFToken($('meta[name="csrf-token"]').attr('content'));
Run Code Online (Sandbox Code Playgroud)

  • 我不同意.这是一个很好的答案,但它没有解决缺乏服务器端渲染的问题.它提到使用Jade在页面上呈现元标记.但是这个标签的价值需要在服务器端生成,因为原始的提问者说他​​的所有观点都不是由服务器端生成的,所以这不起作用. (4认同)

Gre*_*xis 6

server.js

...
// All Cookies/Sessions/BodyParser go first
app.use(express.csrf());
...
// Get the request
app.post('/ajax', function(req, res){
    res.render('somelayout', {csrf_token: req.session._csrf});
});
Run Code Online (Sandbox Code Playgroud)

在somelayout.jade

input(type='hidden', name='_csrf', value=csrf_token)
Run Code Online (Sandbox Code Playgroud)

CSRF中间件仅在每个会话中生成一次csrf令牌,因此在用户访问期间可能不会更改.

此外,它不会检查GET和HEAD请求上的令牌.只要令牌在请求(标题,正文或查询)中,您就是好的.这就是它的全部内容.

  • 感谢您及时的回复.在我的应用程序中,所有客户端内容都是通过ajax执行的.内容(包括模板)的实际呈现在客户端执行.所有服务器都以JSON格式向客户端提供可变数据.这意味着我必须通过ajax检索CSRF令牌以将其呈现到页面中,以便随后可以在ajax post请求中将其发回.我担心从安全的角度来看这可能会有问题,这是一个有效的问题吗? (3认同)