2018-10-02 23:53:28 +00:00
# redirect-https.js
2015-06-19 15:33:15 +00:00
2018-10-03 00:25:04 +00:00
Secure-by-default redirects from HTTP to HTTPS.
2018-10-02 23:49:24 +00:00
2020-04-26 23:40:00 +00:00
- 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
2015-06-19 15:33:15 +00:00
2015-07-09 03:25:03 +00:00
See < https: / / coolaj86 . com / articles / secure-your-redirects / >
2015-07-07 23:19:44 +00:00
## Installation and Usage
2015-06-19 15:33:15 +00:00
```bash
npm install --save redirect-https
```
2015-07-07 23:19:44 +00:00
```js
2020-04-26 23:40:00 +00:00
"use strict";
2015-07-07 23:19:44 +00:00
2020-04-26 23:40:00 +00:00
var express = require("express");
2015-07-07 23:19:44 +00:00
var app = express();
2020-04-26 23:40:00 +00:00
var redirector = require("redirect-https")({
body: "<!-- Hello Developer! Please use HTTPS instead: {{ URL }} --> "
});
app.use("/", redirector);
2015-07-07 23:19:44 +00:00
module.exports = app;
```
## Options
2018-10-03 00:25:04 +00:00
```js
2015-07-07 23:19:44 +00:00
{ 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
2018-10-02 23:49:24 +00:00
, browsers: 301 // issue 301 redirect if the user-agent contains "Mozilla/"
, apis: 'meta' // issue meta redirects to non-browsers
2015-07-07 23:19:44 +00:00
}
```
2020-04-26 23:40:00 +00:00
- 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.
- `{{ URL }}` in the body text will be replaced with a URI encoded and HTML escaped url (it'll look just like it is)
- `{{ HTML_URL }}` in the body text will be replaced with a URI decoded and HTML escaped url (it'll look just like it would in Chrome's URL bar)
- `{{ UNSAFE_URL }}` is the raw, original url
2018-10-03 00:25:04 +00:00
2015-07-07 23:19:44 +00:00
## Demo
2015-06-19 15:33:15 +00:00
```javascript
2020-04-26 23:40:00 +00:00
"use strict";
2015-07-07 23:19:44 +00:00
2020-04-26 23:40:00 +00:00
var http = require("http");
2015-06-19 15:33:15 +00:00
var server = http.createServer();
2015-07-07 23:39:34 +00:00
var securePort = process.argv[2] || 8443;
var insecurePort = process.argv[3] || 8080;
2015-06-19 15:33:15 +00:00
2020-04-26 23:40:00 +00:00
var redirector = require("redirect-https")({
port: securePort,
body: "<!-- Hello! Please use HTTPS instead: {{ URL }} --> ",
trustProxy: true // default is false
});
server.on("request", redirector);
2015-07-07 23:19:44 +00:00
server.listen(insecurePort, function () {
2020-04-26 23:40:00 +00:00
console.log(
"Listening on http://localhost.rootprojects.org:" +
server.address().port
);
2015-07-07 23:19:44 +00:00
});
2015-06-19 15:33:15 +00:00
```
2020-04-26 23:40:00 +00:00
## 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:
```js
{
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).
2018-09-07 19:30:29 +00:00
# Meta redirect by default, but why?
2015-06-19 15:33:15 +00:00
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
< 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
2015-07-07 23:19:44 +00:00
# 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:
2020-04-26 23:40:00 +00:00
- `http://localhost.rootprojects.org:8080/"><script>alert('hi')</script>`
- `http://localhost.rootprojects.org:8080/';URL=http://example.com`
- `http://localhost.rootprojects.org:8080/;URL=http://example.com`