nodejs 的安全

 1.connect中间件csrf

原理:在express框架中csrf 是通过connect 模块的中间件来解决的。其原理是在前端构造一个隐藏的表单域“_csrf” ,后端生成一个值,作为该表单域,然后在提交表单的时候,将这个值提交到后端,后端再根据这个值来比较,如果和之前的值相等的,就认为是正确的,否则就是错误的。 我们来看看代码:

module.exports = function csrf(options) {
  options = options || {};
  var value = options.value || defaultValue;

  return function(req, res, next){
    
    // already have one
    var secret = req.session._csrfSecret;
    if (secret) return createToken(secret);

    // generate secret
    uid(24, function(err, secret){
      if (err) return next(err);
      req.session._csrfSecret = secret;
      createToken(secret);
    });
    
    // generate the token
    function createToken(secret) {
      var token;

      // lazy-load token
      req.csrfToken = function csrfToken() {
        return token || (token = saltedToken(secret));
      };
      
      // compatibility with old middleware
      Object.defineProperty(req.session, '_csrf', {
        configurable: true,
        get: function() {
          console.warn('req.session._csrf is deprecated, use req.csrfToken() instead');
          return req.csrfToken();
        }
      });
      
      // ignore these methods
      if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next();
      
      // determine user-submitted value
      var val = value(req);
      
      // check
      if (!checkToken(val, secret)) return next(utils.error(403));
      
      next();
    }
  }
};

我们看到,直接以function(req,res,next){} 返回,在这个函数里面有一个 createToken 函数,就是生成token 的,将token的值直接绑定在请求对象req的属性上,req.csrfToken = function

我们可以直接调用这个函数,生成值,返回给页面,赋值给表单域。然后表单提交 经过checkToken 函数,比较是否相同,如果是就调用next 函数,否则直接调用utils.error(403) 了。

2. cookie_secret 

express 可以通过connect的中间件模块cookieParser 来解决

使用方法:

connect()
 *       .use(connect.cookieParser('optional secret string'))
 *       .use(function(req, res, next){
 *         res.end(JSON.stringify(req.cookies));
 *       })

3.paypal 的lusca 模块

这个模块很简洁,可以解决csrf,p3p,xframe,csp 等问题。使用起来很简单。官方地址

原理: csrf 是直接调用express 框架的csrf来解决的,p3p和xframe ,csp 都是设置response header 来解决的。

调用方式为:

var express = require('express'),
    appsec = require('lusca'),
    server = express();

server.use(appsec.csrf());
server.use(appsec.csp({ /* ... */}));
server.use(appsec.xframe('SAMEORIGIN'));
server.use(appsec.p3p('ABCDEF'));

也可以直接这么使用

server.use(appsec({
    csrf: true,
    csp: { /* ... */},
    xframe: 'SAMEORIGIN',
    p3p: 'ABCDEF' 
}));

 

posted @ 2013-12-26 18:23  yupeng  阅读(5392)  评论(0编辑  收藏  举报