nodejs 的安全

yupeng發表於2013-12-26

 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' 
}));

 

相關文章