简体   繁体   中英

CSURF not working if the Session cookie is secure

I am stumped as to when I set the cookie to secure, the csrf of node is not working.

//Load Cooike Parser
app.use(cookieParser(secret));
//Load Session Store
app.use(require('express-session')({
    secret:secret,
    cookie:{
        maxAge: 1000 * 60 * 60 * 24, // 1 day,
        secure: true,
        httpOnly: true
    },
    store: sessionStore
}));
//Load POST data parser
//Form sent should be in JSON format
app.use(bodyParser.json());

//Initiate CSRF on middleware
//set the CSRF cookie Header
app.use(csrf());
app.use(function(req,res,next){
    res.cookie('XSRF-TOKEN',req.csrfToken());
    next();
});

This setup is using MongoDB for storing the session data. Reading on the express-session docs, I come across to this ...

Please note that secure: true is a recommended option. However, it requires an https-enabled website , ie, HTTPS is necessary for secure cookies. If secure is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using secure: true, you need to set "trust proxy" in express:

Source: npm express-session

I'm currently running the site locally, so it's not HTTPS. I would like to know is how does secure:true relate to the not passing the csrf test?

Since the provided code sample does not cover the creation of the form I will assume that you correctly include the _csrf value. Or that you set the corresponding header with JavaScript.

Let's start by explaining why you shouldn't be doing res.cookie('XSRF-TOKEN',req.csrfToken()); .

The default way that csurf module works is it generates or returns the _csrf token when you run req.csrfToken() , but it also saves this token in the session.

If you want to use cookie instead of the session as the storage method you should be passing cookie: true or cookie: cookieOptions as the initialisation value to csurf instead of manually setting the cookie.

This is relevant because if you don't use the intended option parameter the csurf will try to look up the token value for verification from the session object, which means your cookie setting is useless.

Now as for the part why it fails on HTTPS.

When you set secure: true what it does is send cookies from the server to the browser with the secure flag.

As per the OWASP page :

The secure flag is an option that can be set by the application server when sending a new cookie to the user within an HTTP Response. The purpose of the secure flag is to prevent cookies from being observed by unauthorized parties due to the transmission of a the cookie in clear text.

To accomplish this goal, browsers which support the secure flag will only send cookies with the secure flag when the request is going to a HTTPS page . Said in another way, the browser will not send a cookie with the secure flag set over an unencrypted HTTP request .

This includes the session token cookie, which is used to look up information in the sessionStore.

So the browser does not send a session cookie to the server. The server creates a new empty session and because we are back to the default csurf operating method it will try to look up a token from an empty session. There will not be a token so the comparison will fail.

As a side note this also means that your session in general fail.

NB! As a side note if you are more interested I suggest you read the OWASP CSRF mitigation cheatsheet . Or my book about Node.js Web Application Security , which among other things covers the CSRF and various mitigation methods implemented with Node.js.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM