50.6. Helmet - A Security Helmet

Below you will find a series of uses of helmet for protecting against cross-stie scripting (XSS), insecure requests, and clickjacking. They are all quotes from [Kor18].

Helmet is collection of 12 middleware functions that allow you to set specific HTTP headers for you server's protection. The examples quotes here are from https://www.securecoding.com/blog/using-helmetjs/. Please check that, the documentation or [Kor18], for more specifics. The prerequisite for all the examples is that your app.js requires helmet, and contains the relevant example from below.

Example 50.4. Fragment of app.js
const helmet = require("helmet");                       // nml added
...
const app = express();
...
// setup/config
app.use(helmet());                                      // nml added

Without helmet the HTTP headers are:

$ curl http://localhost:3000 -I
HTTP/1.1 404 Not Found
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 1481
ETag: W/"5c9-S5bt/uggeQCWo4g7/xyWHg2TZKE"
Date: Tue, 17 May 2022 11:38:48 GMT
Connection: keep-alive
Keep-Alive: timeout=5

With app.use(helmet()); the HTTP headers as a default are:

$ curl http://localhost:3000 -I       
HTTP/1.1 200 OK

Content-Security-Policy: default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
X-DNS-Prefetch-Control: off
Expect-CT: max-age=0
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Download-Options: noopen
X-Content-Type-Options: nosniff
Origin-Agent-Cluster: ?1
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: no-referrer
X-XSS-Protection: 0

Content-Type: text/html; charset=utf-8
Content-Length: 437
ETag: W/"1b5-+fUDnd1MUeXA/MhRnTHTO9cySys"
Date: Tue, 17 May 2022 07:03:49 GMT
Connection: keep-alive
Keep-Alive: timeout=5

The lines between the two empty lines contain what is added by helmet. Please notice that the X-Powwered-By is removed by helmet. Following this, please find the format of some of the possible configuration declarations.

Example 50.5. Header: Content-Security-Policy, with Additions

app.use(
  helmet.contentSecurityPolicy({
    useDefaults: true,
    directives: {
      "script-src": ["'self'", "securecoding.com"],
      "style-src": null,
    }
  })
);

Example 50.6. Header: X-DNS-Prefetch-Control

This adds to user privacy.

app.use(
  helmet.dnsPrefetchControl({
    allow: false
  })
);

Example 50.7. X-Powered-By

Do not help Mallory's reconnaissance. The default behavior of helmet removes this header. You may do

app.use(helmet.hidePoweredBy({setTo: 'Django/1.2.2 SVN:65334'}));

to mislead Mallory.


Example 50.8. Referer-Policy
app.use(
  helmet.referrerPolicy({
    policy: ["same-origin"]
  })
);

Example 50.9. X-XSS-Protection

Necessary addition to browser built in protection.

app.use(helmet.xssFilter());