You need to sign in or sign up before continuing.
Name Last Update
..
LICENSE Loading commit data...
README.md Loading commit data...
example.js Loading commit data...
index.js Loading commit data...
package.json Loading commit data...
test.js Loading commit data...

redirect-https

Secure-by-default redirects from HTTP to HTTPS.

  • Browsers get a 301 + Location redirect
  • Only developers, bots, and APIs see security warning (advising to use HTTPS)
  • Always uses meta redirect as a fallback, for everyone
  • '/' always gets a 301 (for curl | bash installers)
  • minimally configurable, don't get fancy

See https://coolaj86.com/articles/secure-your-redirects/

Installation and Usage

npm install --save redirect-https
'use strict';

var express = require('express');
var app = express();

app.use('/', require('redirect-https')({
  body: '<!-- Hello Mr Developer! Please use HTTPS instead -->'
}));

module.exports = app;

Options

{ port: 443           // defaults to 443
, body: ''            // defaults to an html comment to use https
, trustProxy: true    // useful if you haven't set this option in express
, browsers: 301       // issue 301 redirect if the user-agent contains "Mozilla/"
, apis: 'meta'        // issue meta redirects to non-browsers
}
  • This module will call next() if the connection is already tls / https.
  • If trustProxy is true, and X-Forward-Proto is https, next() will be called.
  • If you use {{URL}} in the body text it will be replaced with a URI encoded and HTML escaped url (it'll look just like it is)
  • If you use {{HTML_URL}} in the body text it will be replaced with a URI decoded and HTML escaped url (it'll look just like it would in Chrome's URL bar)

Advanced Options

For the sake of curl | bash installers and the like there is also the option to cause bots and apis (i.e. curl) to get a certain redirect for an exact path match:

{ paths: [
    { match: '/'
    , redirect: 301
    }
  , { match: /^\/$/
    , redirect: 301
    }
  ]
}

If you're using this, you're probably getting too fancy (but hey, I get too fancy sometimes too).

Demo

'use strict';

var http = require('http');
var server = http.createServer();
var securePort = process.argv[2] || 8443;
var insecurePort = process.argv[3] || 8080;

server.on('request', require('redirect-https')({
  port: securePort
, body: '<!-- Hello! Please use HTTPS instead -->'
, trustProxy: true // default is false
}));

server.listen(insecurePort, function () {
  console.log('Listening on http://localhost.pplwink.com:' + server.address().port);
});

Meta redirect by default, but why?

When something is broken (i.e. insecure), you don't want it to kinda work, you want developers to notice.

Using a meta redirect will break requests from curl and api calls from a programming language, but still have all the SEO and speed benefits of a normal 301.

<html><head>
<meta http-equiv="refresh" content="0;URL='https://example.com/foo'" />
</head><body>
<!-- Hello Mr. Developer! Please use https instead. Thank you! -->
</html>

Other strategies

If your application is properly separated between static assets and api, then it would probably be more beneficial to return a 200 OK with an error message inside

Security

The incoming URL is already URI encoded by the browser but, just in case, I run an html escape on it so that no malicious links of this sort will yield unexpected behavior:

  • http://localhost.pplwink.com:8080/"><script>alert('hi')</script>
  • http://localhost.pplwink.com:8080/';URL=http://example.com
  • http://localhost.pplwink.com:8080/;URL=http://example.com