HTTPS redirection for all routes node.js/express - Security concerns

15,756

Solution 1

function requireHTTPS(req, res, next) {
    if (!req.secure) {
        //FYI this should work for local development as well
        return res.redirect('https://' + req.get('host') + req.url);
    }
    next();
}

app.use(requireHTTPS);
app.get('/', routeHandlerHome);

The middleware approach will work because express will run the middleware in the order added, before it runs the router, and in general this kind of site-wide policy is cleaner as middleware vs. a wildcard route.

Regarding question 2 about sniffing session cookies, that must be addressed by marking the cookies as secure when you set them. If they haven't been marked secure, the browser will transmit them with HTTP requests as well, thus exposing them to sniffing.

Solution 2

You can simply use your https_redirect function (though a bit modified) as a to automatically redirect all of your secure requests:

// force https redirect
var https_redirect = function () {
  return function(req, res, next) {
    if (req.secure) {
      if(env === 'development') {
        return res.redirect('https://localhost:3000' + req.url);
      } else {
        return res.redirect('https://' + req.headers.host + req.url);
      }
    } else {
      return next();
    }
  };
};
app.use(https_redirect());

app.get('/', routeHandlerHome);
Share:
15,756

Related videos on Youtube

los7world
Author by

los7world

Updated on September 14, 2022

Comments

  • los7world
    los7world over 1 year

    I recently took a stab at setting up HTTPS on a node/express server. I have successfully managed to redirect all the routes to use https using the code below:

    // force https redirect
    var https_redirect = function(req, res, next) {
      if (req.secure) {
        if(env === 'development') {
          return res.redirect('https://localhost:3000' + req.url);
        } else {
          return res.redirect('https://' + req.headers.host + req.url);
        }
      } else {
        return next();
      }
    };
    
    app.get('*', function(req, res, next) {
      https_redirect(req, res, next);
    });
    

    This seems to be working fine. However, since I havent' dabbled into this before I have a couple of questions:

    1. Is this the ideal way to redirect from http to https?
    2. If a user uses the http route, prior to the redirect is it possible for anyone to use something like sslstrip to sniff out session info.

    node: v0.8.2 ; express: v3.05

  • los7world
    los7world about 11 years
    Hey Josh. Thanks for the reply. Can you highlight how your approach specifically with app . use would work as compared to my implementation.
  • red
    red about 11 years
    @los7world: With app.use(), you're specifically setting up a middleware with no route matching, thus all your routes will pass through it.
  • los7world
    los7world about 11 years
    Understood. Thanks for your input.
  • Gingi
    Gingi almost 10 years
    This is great, but it's slightly problematic for development if you're using non-standard (80 for HTTP, 443 for HTTPS), because it tries to redirect to https://localhost:[PORT]. A workaround is to set an SSL_PORT environment variable in the development environment, and, if it's defined, replace the port. See here for the modified snippet.
  • alexsc
    alexsc almost 9 years
    hei, how can I connect with a front-end client after doing this ? Thanks !
  • Mladen Janjetovic
    Mladen Janjetovic over 7 years
    Shouldn't this first condition be !req.secure
  • S.Kiers
    S.Kiers about 7 years
    As a note, on heroku you have to use req.headers['x-forwarded-proto'] !== 'https' or else this will not work. See stackoverflow.com/questions/7185074/…