Express CSRF token validation

谁都会走 提交于 2019-12-18 04:52:56

问题


I'm having issues with CSRF tokens. When I submit a form, a new XSRF-TOKEN is being generated but I think I'm generating two different tokens, I'm kinda confused. There's also a token called _csrf, so I see two different cookies in developer tools (XSRF-TOKEN and _csrf), _csrf doesn't change after a post.

What I want to do is to generate a new token for each post request and check whether it's valid or not. One thing I know that I should do it for security, but I stuck.

It has been a long day and I'm new into Express and NodeJS.

Here's my current setup.

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

Routes

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>

回答1:


Based on the amount of code you shared, a few things don't look correct:

1 . You may need to swap these lines so that csrf runs before the routes.

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

2 . These lines need to be placed before the routes.

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 . Use locals.csrftoken in your form

<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>



回答2:


the token in the cookie will be completely different than the one in the express session. you want to check for one or the other not both.

i would disable the cookies entirely! as it worked for me.

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

the author mentions it here https://github.com/expressjs/csurf/issues/52

next you want to the "X-CSRF-Token" to the header on ajax post found here: Express.js csrf token with jQuery Ajax




回答3:


Below code is working for me. Let me know in case you still face issue.

As mentioned that you wish to use cookies, you have make csurf aware that you are using cookies for setting the CSRF token.

Step1: Configuration

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

Step2: In the route,

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

Step3: Include a hidden field in the HTML for csrf token Example:

<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>


来源:https://stackoverflow.com/questions/33060044/express-csrf-token-validation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!