expressjs / csurf

CSRF token middleware
MIT License
2.3k stars 217 forks source link

Cannot validate CSRF token using the example code #135

Closed lobax closed 6 years ago

lobax commented 6 years ago

I am unable to use csurf in this basic test application, no matter what I do I always get "ForbiddenError: invalid csrf token" after sending a form.

What am I doing wrong? I am trying to follow the example given in the documentation for csurf (although I am using TLS as well - could that affect the results?).

'use strict'

var https = require('https');
var express = require('express');
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var fs = require('fs');
var oauth = require('./oauth.js');
var argv = require('minimist')(process.argv.slice(2), {
    alias: {p: 'port'},
    default: {port: 80},
});

// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })

var app = express();

app.use(cookieParser());

// Init SSL
var sslPath = '/etc/letsencrypt/live/censored/';
var options = {
    key: fs.readFileSync(sslPath + 'privkey.pem'),
    cert: fs.readFileSync(sslPath + 'fullchain.pem')
};

app.get('/some-form', csrfProtection, function(req, res){
        res.send('<form action="/process" method="POST">' +
                    '<input type="hidden" name="_csrf" value="' + req.csrfToken() + '">' +
                    'Favorite color: <input type="text" name="favoriteColor">' +
                    '<button type="submit">Submit</button>' +
                    '</form>');
});

app.post('/process', csrfProtection, function(req, res){
        res.send('<p>Your favorite color is "' + req.body.favoriteColor + '".');
});

app.get("/", function(req, res) {
    res.send('Hello World!');
});
app.listen(argv.port, function() {
    console.log('listening on port ' + argv.port);
});

https.createServer(options, app).listen(443);
dougwilson commented 6 years ago

Looks like you just forgot to actually use the parseForm you created, so the _csrf was not visible to the csurf middleware (csrfProtection). Just use the parseForm somewhere prior to that and it works 👍

lobax commented 6 years ago

Ah, thanks! Maybe this should also be done in the example? :)

dougwilson commented 6 years ago

It's in the example, right in the post handler:

app.post('/process', parseForm, csrfProtection, function (req, res) {
  res.send('data is being processed')
})
lobax commented 6 years ago

Thank you, I am blind!