Node.js csrf攻撃防止

5875 ワード

csurf


Node.js csrf攻撃ミドルウェア防止
セッションミドルウェア(express-sessionなど)またはクッキーミドルウェア(cookie-parser)が最初に初期化される必要がある
  • cookieオプションがfalse以外の値に設定されている場合は、このモジュールの前にcookie-parser
  • を参照する必要があります.
  • それ以外に、このモジュールの前にsessionミドルウェアを使用する必要があります.
  • express-session
  • cookie-session


  • インストール


    npmでインストール:
    npm install csurf
    

    API

    var csurf = require('csurf')
    

    csurf([options])


    CSRFトークンの作成と検証のために、req.csrfToken()関数に追加されるべきトークンを作成するミドルウェアを作成します.これらのトークンは、非表示フォームフィールド、query-stringなど、随時変更されます.トークンは、アクセス者のセッションとクッキーに基づいて検証されます.

    options


    csurf関数には、次の任意のキーを含むオプションoptionsオブジェクトがあります.
  • cookie

  • ユーザのトークン秘密がクッキーまたはreq.sessionに存在するかどうかを決定する.デフォルトはfalseです.
    クッキーがtrueに設定されると、モジュールはreq.sessionを使用しない動作を変更します.セッションミドルウェアを使用する必要がないことを意味します.逆に、このアセンブリの前に、cookie-parserミドルウェアを使用するだけです.
    var csurf = require('csurf');
    
    csurf({cookie:true})
    

    クッキーがオブジェクトに設定されると、クッキーの秘密記憶が有効になり、この機能のオプションが含まれる(trueに設定されると、デフォルトのオプションが使用される).これらのオプションには、次のいずれかのキーが含まれます.
    csurf({cookie:{
        key: '_csrf',
        path: '/'
    }})
    
  • key-トークンを格納するためのクッキー名(デフォルト:_csrf)
  • path-cookieのパス(デフォルト:/)
  • その他のオプションはres.cookieを参照
  • ignoreMethods

  • CSRFトークンチェックを無効にする方法のセット.デフォルト[GET,'HEAD','OPTIONS']
    csurf({
        ignoreMethods: [GET,'HEAD','OPTIONS']
    })
    
  • sessionKey

  • セッションオブジェクト上のreq上にある属性(「key」)を決定します.デフォルトのsession(req.sessionなど).フレームワークからのCSRFトークンが格納され、req[sessionKey].csrfSecretのように取得される.cookieのオプションがfalseでない場合、このオプションは無効です.
  • value

  • 検証のために、要求から読み出したトークンを呼び出すためにミドルウェア関数が提供されます.この関数value(req)が呼び出されます.トークンは、文字列で返されることが予想されます.
    デフォルト値は、次の順序でトークンを読み込む関数です.
  • req.body._csrf-典型的にはbody-parserモジュールによって生成される.
  • req.query._csrf - express.jsは、URLからのクエリー文字列
  • を取得するために内蔵されている.
  • req.headers['csrf-token']-CSRF-Token HTTPリクエストヘッダ
  • .
  • req.headers['xsrf-token']-XSRF-Token HTTPリクエストヘッダ
  • .
  • req.headers['x-csrf-token']-X-CSRF-Token HTTPリクエストヘッダ
  • .
  • req.headers['x-xsrf-token']-X-XSRF-Token HTTPリクエストヘッダ
  • .


    express


    サービス側とクライアント側でそれぞれ操作する必要があります。


    サービス側コードの例を次に示し、CSRFトークンの発行が必要なフォームを生成します。

    var express = require('express'),             // express  
        bodyparser = require('body-parser'),      //   POST,           URL   
        cookieParser = require('cookie-parser'),  // cookie   ,csurf    
        csrf = require('csurf');                  // csurf   
    
    
    //        
    var csrfProtection = csrf({cookie:true}),
        parseForm = bodyParser.urlencodeed({extended:false});
    
    //   epxress app
    var app = express();
    
    // cookies
    //    ,   csrfProtection  "cookie"    true,    cookie
    app.use(cookieParser());
    
    app.get('/form', csrfProtection, function (req, res) {
        //   csrfToken      
        res.render('send', { csrfToken: req.csrfToken() })
    })
    
    app.post('/process', parseForm, csrfProtection, function (req, res) {
        res.send('data is being processed')
    })
    

    以下に、クライアントコードの例を示します(テンプレート言語に依存し、ここではhandlebarsを例に挙げます).csrfTokenの値を、非表示ドメインフィールド名_csrfの値として設定します.
    Favorite color:

    ルーティングを無視


    注意:
  • は、当サイト以外の要求が検証を必要としないことを許可し、CSRF検証を無効にすることができる.
  • 自分のサイトだけにCSRF認証の有効化を要求しないでください.
  • は、認証ユーザに属していても、CSRF攻撃を防ぐのに十分ではないセッションが存在する.

  • 以下に、いくつかのルーティングが有効なCSRFトークンを検証しないように、理由を要求する方法の例を示す.
    var express = require('express'),             // express  
        bodyparser = require('body-parser'),      //   POST,           URL   
        cookieParser = require('cookie-parser'),  // cookie   ,csurf    
        csrf = require('csurf');                  // csurf   
    
    
    var app = express()
    
    //   api  
    var api = function(){
        var router = new express.Router()
    
        router.post('/getProfile', function (req, res) {
            res.send('    csrf')
        })
    
        return router
    }
    
    //  crsf      api   ,  csrf  
    app.use('/api', api)
    
    //   "/api"  ,     crsf      
    app.use(bodyParser.urlencoded({ extended: false }))
    app.use(cookieParser())
    app.use(csrf({ cookie: true }))
    
    app.get('/form', function (req, res) {
        //   csrfToken      
        res.render('send', { csrfToken: req.csrfToken() })
    })
    

    カスタムエラー処理


    CSRFトークンの検証に失敗すると、エラーerr.code === 'EBADCSRFTOKEN'が投げ出される.これにより、カスタムエラー情報を表示できます.
    var express = require('express'),             // express  
        bodyparser = require('body-parser'),      //   POST,           URL   
        cookieParser = require('cookie-parser'),  // cookie   ,csurf    
        csrf = require('csurf');                  // csurf   
    
    var app = express()
    app.use(bodyParser.urlencoded({ extended: false }))
    app.use(cookieParser())
    app.use(csrf({ cookie: true }))
    
    //     
    app.use(function (err, req, res, next) {
        if (err.code !== 'EBADCSRFTOKEN') return next(err)
    
        // CSRF    
        res.status(403)
        res.send('form tampered with')
    })