Serve everything over HTTPS

301 http to https, load nothing over http, send HSTS.

Helmethelmetjs.github.io
helmet.js
Express security headersRead docs ↗

From security-best-practices (HTTPS only) and seo-audit, HTTPS.

Follow the request

Press Visit twice, then try a subdomain.

Serves http as isBad
Not secure about:blank
    0 requests
    301 + HSTSGood
    Not secure about:blank
      0 requests
      app.set("trust proxy", 1); // so req.secure reads X-Forwarded-Proto
      
      app.use(helmet({
        hsts: { maxAge: 31536000, includeSubDomains: true, preload: true },
      }));
      
      app.use((req, res, next) => {
        if (process.env.NODE_ENV === "production" && !req.secure) {
          return res.redirect(301, `https://${req.headers.host}${req.url}`);
        }
        next();
      });

      Find the mixed content

      Press Pay, then switch each resource to https.

      shop.example.comMixed
      Not fully secure shop.example.com/checkout
      Image failed
      Trail runner$48.00
      Card ending 4242 Payment widget did not load
      Subresources
      img
      script
      form
      Console
        <img src="https://cdn.example.com/shoe.jpg" alt="Trail runner">
        <script src="https://cdn.example.com/pay.js" defer></script>
        <form action="/pay" method="post">…</form>
        
        # Safety net, not a fix:
        Content-Security-Policy: upgrade-insecure-requests

        Build the HSTS header

        Lower max-age or untick a directive.

        HSTS headerPreload-ready
        • max-age at least 31536000
        • includeSubDomains
        • preload

        Why it matters, pros and cons

        Why it matters

        Anything over http can be read and rewritten. HSTS removes the last plain hop.

        Pros

        • Cookies and payment data travel encrypted.
        • Old http links never leave in plaintext.
        • Unlocks HTTP/2 and secure-context APIs.

        Cons

        • HSTS on localhost pins your dev server to https.
        • Preload is slow to undo; every subdomain needs https.
        • Start with a short max-age, then raise it.