expressjs / csurf

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

Disable CSRF checking during tests #140

Closed realmhamdy closed 6 years ago

realmhamdy commented 6 years ago

Currently I'm trying to test my expressjs POST routes using Mocha/Chai. Without manual intervention all post requests fail with such a trace: POST /users/new ForbiddenError: invalid csrf token at csrf (/vagrant/node_modules/csurf/index.js:112:19) at Layer.handle [as handle_request] (/vagrant/node_modules/express/lib/router/layer.js:95:5) So I searched around and found this this answer from which I wrote this in my tests:

let should = chai.should()
// preserve token and agent
let csrfToken, agent

before((done) => {
    agent = chai.request(server)
    agent.get("/_csrf")
        .end((err, res) => {
            csrfToken = res.body.csrf
            done()
        })
})

// the test
it("should create a user when valid user data is posted", (done) => {
        agent.post("/users/new")
            .send({ username: "validUserName", password1: "123456", password2: "123456", _csrf: csrfToken })
            .end((err, res) => {
...

So I'm passing the token (which I checked to be a real value) but the test is still failing. Can somebody tell me why this is not working?

Me having used django, I never had to deal with the problem because CSRF checks are disabled by default during tests. Is this something that can (should) be achieved with csurf? Like disable CSRF if NODE_ENV == "test"?

dougwilson commented 6 years ago

So your getting the token and submitting it during test would work if you also submitting the cookie as well. Without the cookie, the session is not known.

This module did used to disable checks when under test, but that was found to be a security vulunerability by the secuirty community, because they say people can end up where they have a server running with the checks off and not realize, so we had to remove the feature. If you do want that feature back, you'll have to add it back in user-land, like the following:

app.use(
  process.end.NODE_ENV === 'test' ?
    csurf({ ignoreMethods: ['GET', 'HEAD', 'OPTIONS', 'POST', 'PUT' /* etc */] })
    csurf()
)

I hope this helps!