web-dev-qa-db-ja.com

ExpressCSRFトークンの検証

CSRFトークンに問題があります。フォームを送信すると、新しいXSRF-TOKENが生成されますが、2つの異なるトークンを生成していると思います。ちょっと、混乱しています。 _csrfというトークンもあるので、開発者ツール(XSRF-TOKENと_csrf)に2つの異なるCookieがあり、_csrfは投稿後に変更されません。

私がやりたいのは、POSTリクエストごとに新しいトークンを生成し、それが有効かどうかを確認することです。セキュリティのためにやるべきだと私が知っていることの1つですが、私は立ち往生しました。

長い一日でしたが、ExpressとNodeJSは初めてです。

これが私の現在の設定です。

var express = require('express')
  , passport = require('passport')
  , flash = require('connect-flash')
  , utils = require('./utils')
  , csrf = require('csurf')
  // setup route middlewares
  ,csrfProtection = csrf({ cookie: true })
  , methodOverride = require('method-override')
  , bodyParser = require("body-parser")
  , parseForm = bodyParser.urlencoded({ extended: false })
  , cookieParser = require('cookie-parser')
  , cookieSession = require('cookie-session')
  , LocalStrategy = require('passport-local').Strategy
  , RememberMeStrategy = require('../..').Strategy;


var app = express();

app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.engine('ejs', require('ejs-locals'));
app.use(express.logger());
app.use(express.static(__dirname + '/../../public'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());
app.use(express.session({ secret: 'keyboard cat' }));
app.use(flash());
// Initialize Passport!  Also use passport.session() middleware, to support
// persistent login sessions (recommended).
app.use(passport.initialize());
app.use(passport.session());
app.use(passport.authenticate('remember-me'));
app.use(app.router);
app.use(csrf());

app.use(function (req, res, next) {
  res.cookie('XSRF-TOKEN', req.csrfToken());
  res.locals.csrftoken = req.csrfToken();
  next();
});

ルート

app.get('/form', csrfProtection, function(req, res) {
  // pass the csrfToken to the view
  res.render('send', { csrfToken: req.csrfToken()});
});

app.post('/process', parseForm, csrfProtection, function(req, res) {
  res.send('data is being processed');
});

send.ejs(/ form GET)

<form action="/process" method="POST">
  <input type="hidden" name="_csrf" value="<%= csrfToken %>">

  Favorite color: <input type="text" name="favoriteColor">
  <button type="submit">Submit</button>
</form>
7
salep

共有したコードの量に基づいて、いくつかの点が正しくないように見えます。

1。 csrfがルートの前に実行されるように、これらの行を交換する必要がある場合があります。

app.use(app.router);
app.use(csrf());

2。これらの線は、ルートの前に配置する必要があります。

app.use(csrf());
app.use(function (req, res, next) {
  res.cookie('XSRF-TOKEN', req.csrfToken());
  res.locals.csrftoken = req.csrfToken();
  next();
});
app.use(app.router);

3。使用する locals.csrftokenあなたのフォームで

<form action="/process" method="POST">
  <input type="hidden" name="_csrf" value="<%= csrftoken %>">

  Favorite color: <input type="text" name="favoriteColor">
  <button type="submit">Submit</button>
</form>
12
Filype

以下のコードは私のために働いています。それでも問題が発生する場合はお知らせください。

Cookieを使用したい場合は、CSRFトークンの設定にCookieを使用していることをcsurfに認識させます。

ステップ1:構成

var csrf = require('csurf');
var cookieparser= require('cookie-parser'); 

//cookieparser must be placed before csrf 
app.use(bodyparser.urlencoded({extended:false}));
app.use(cookieParser('randomStringisHere222'));
app.use(csrf({cookie:{key:XSRF-TOKEN,path:'/'}}));

//add the your app routes here
app.use("/api", person);
app.use("/", home);

ステップ2:ルートでは、

res.render('myViewPage',{csrfTokenFromServer:req.csrfToken()}); 

ステップ3:csrfトークンのHTMLに非表示フィールドを含める例:

<form action="/api/person" method="POST">
      <input type="hidden" name="_csrf" value=<%=csrfTokenFromServer %> />
      First name:<br>
      <input type="text" name="firstname" value="">
      <br>
      Last name:<br>
      <input type="text" name="lastname" value="">
      <br><br>
      <input type="submit" value="Submit">
 </form>
0
Laxmeesh Joshi

cookie内のトークンは、エクスプレスセッション内のトークンとは完全に異なります。両方ではなく、どちらか一方をチェックしたい。

私はクッキーを完全に無効にします!それが私のために働いたので。

var csrfProtection = csurf({cookie:false});

著者はここでそれについて言及しています https://github.com/expressjs/csurf/issues/52

次に、ここにあるajax投稿のヘッダーに「X-CSRF-Token」を追加します。 Express.js csrf token with jQuery Ajax

0
Michael P.