Have you ever had a website where you switched from HTTP to HTTPS and there were some residual redirects still redirecting to HTTP? HSTS is a web security policy mechanism to mitigate protocol downgrade attacks and cookie hijacking.
HSTS effectively forces the client (browser accessing your server) to direct all traffic through HTTPS – a “secure or not at all” ideology!
Express JS doesn’t allow us to add this header by default, so we’ll use Helmet, a node module that allows us to do this. Install Helmet by running
npm install --save helmet
Then we just have to add it as a middleware to our Express server:
const https = require("https"),
fs = require("fs"),
helmet = require("helmet");
const options = {
key: fs.readFileSync("/srv/www/keys/my-site-key.pem"),
cert: fs.readFileSync("/srv/www/keys/chain.pem")
};
const app = express();
app.use(helmet()); // Add Helmet as a middleware
app.use((req, res) => {
res.writeHead(200);
res.end("hello world\n");
});
app.listen(8000);
https.createServer(options, app).listen(8080);
In order to skip some complicated math, let’s cut to the chase. In very simple terms, there are two different keys used for encryption, the certificate we get from the certificate authority and one that’s generated by the server for key exchange. The default key for key exchange (also called Diffie–Hellman key exchange, or DH) uses a “smaller” key than the one for the certificate. In order to remedy this, we’ll generate a strong DH key and feed it to our secure server for use.
In order to generate a longer (2048 bit) key, you’ll need openssl
, which you probably have installed by default. In case you’re unsure, run openssl -v
. If the command isn’t found, install openssl
by running brew install openssl
:
openssl dhparam -out /var/www/example/sslcert/dh-strong.pem 2048
Then copy the path to the file to our configuration:
// ...
const options = {
key: fs.readFileSync("/var/www/example/sslcert/privkey.pem"),
cert: fs.readFileSync("/var/www/example/sslcert/fullchain.pem"), // these paths might differ for you, make sure to copy from the certbot output
dhparam: fs.readFileSync("/var/www/example/sslcert/dh-strong.pem")
};
// ...