Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secure cookies over reverse proxy with https #251

Closed
akoskm opened this issue Jan 7, 2016 · 7 comments
Closed

Secure cookies over reverse proxy with https #251

akoskm opened this issue Jan 7, 2016 · 7 comments
Assignees
Labels

Comments

@akoskm
Copy link

@akoskm akoskm commented Jan 7, 2016

The following configuration properly produces secure cookies, however

var config = require(configPath),
    express = require('express'),
    cookieParser = require('cookie-parser'),
    session = require('express-session'),
    mongoStore = require('connect-mongo')(session),
    csrf = require('csurf'),
    ....
    sessionConfig = {
      // according to https://github.com/expressjs/session#resave
      // see "How do I know if this is necessary for my store?"
      resave: false,
      saveUninitialized: true,
      secret: config.cryptoKey,
      store: new mongoStore({ url: config.mongodb.uri }),
      cookie: {}
    };

app.use(cookieParser(config.cryptoKey));
if (node_env === "prod") {
    app.set('trust proxy', 1);
    sessionConfig.cookie.secure = true;
    logger.info("using secure cookies");
}
app.use(session(sessionConfig));

I'm getting a new sessionID for every subsequent request fired during a pageload. My application is sitting behind apache which acts as a reverse proxy and has https, the application itself is running on http.

This is not the case if I skip setting sessionConfig.cookie.secure = true; or setting sessionConfig.cookie.secure = false; and the same sessionID is assigned to every request during single or multiple pageloads while I'm firing requests from the same browser instance.

Do you have any idea why I'm getting new sessionID for every request made in a single pageload, is this the intended behavior?

@dougwilson
Copy link
Member

@dougwilson dougwilson commented Jan 10, 2016

Hi!

Do you have any idea why I'm getting new sessionID for every request made in a single pageload, is this the intended behavior?

99% of the time, this is because the Cookie header in the request that reached Express was either missing (thus this module thinks there is no session and creates a new one) or somehow it's a stale cookie.

Diagnosing this is probably going to have to lean on you, who can reproduce the issue with your setup (as it's likely a setup/configuration issue), but I can help you with tips! My first tip would be to completely delete all cookies from the web browser you are testing with to see if that solves the issue.

If that does not help, I suggest using a tool external to the web browser like Wireshark or Fiddler to inspect the request your web browser is making to your Apache server. Because you are using SSL, you'll need to load that tool with the private key of your server so it can decrypt the traffic. Verify that there is a Cookie header in the request and it contains the session ID you expect.

If that looks right, then it's possible it's getting lost somewhere in the Node.js application. I suggest connecting a debugger to your Node.js server and setting a breakpoint within Express's source code, probably here: https://github.com/strongloop/express/blob/4.13.3/lib/application.js#L158 At that point, inspect req.headers.cookie to see if it contains the content you expect. If it does, simply start stepping through the code to see what is happening and if it gets lost, overwritten, or if some condition is hit somewhere that prevents the session from being loaded.

@dougwilson dougwilson self-assigned this Jan 10, 2016
@akoskm
Copy link
Author

@akoskm akoskm commented Jan 12, 2016

Thanks for the detailed answer!

I'm still investigating the issue but seems that this is happening because of my apache configuration. I modified the logging syntax to include cookies and I've noticed that the Secure and HttpOnly cookies are lost somewhere between apache and the application itself and they are never reaching the client side.

I'm closing this issue now but I'll post any updates I have.

@akoskm akoskm closed this Jan 12, 2016
@dougwilson dougwilson added the question label Jan 12, 2016
@lagden
Copy link

@lagden lagden commented Feb 24, 2016

@akoskm Any update about it?

I got the same problem!
The config bellow was my last attempt:

<VirtualHost *:80>
  ServerName nimble.com.br
  Redirect permanent / https://nimble.com.br/
</VirtualHost>

<VirtualHost *:443>
  ServerName nimble.com.br
  Use configSSL nimble.com.br # Macro for SSL
  # Proxy
  ProxyPass / http://127.0.0.1:3001/
  ProxyPassReverse / http://127.0.0.1:3001/
  ProxyPassReverseCookiePath / /
  ProxyPassReverseCookieDomain 127.0.0.1 nimble.com.br
</VirtualHost>
@dougwilson
Copy link
Member

@dougwilson dougwilson commented Feb 25, 2016

Hi @akoskm, your issue is you have not finished standard reverse proxy configuration. Googling around for Apache setup information, it looks like you need to add RequestHeader set X-Forwarded-Proto "https" to your SSL virtual host declaration.

@akoskm
Copy link
Author

@akoskm akoskm commented Feb 25, 2016

@dougwilson that's correct. After adding that config line and reloading apache2 looks like I'm having secure cookies. Thank you!

@lagden looks like you have the same problem.

@lagden
Copy link

@lagden lagden commented Feb 26, 2016

@dougwilson and @akoskm

Yeahh!! That's it!!

Tks!

@nagman
Copy link

@nagman nagman commented May 14, 2019

@dougwilson Thanks man!!!
In my case, I had to set this header on both Apache and Nginx because my project looks like this:
[Apache]===>[Docker (Nginx)===>(Express)]

@expressjs expressjs locked as resolved and limited conversation to collaborators May 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.