Skip to content

Don't upgrade insecure requests when the page is served over HTTP #480

Open
@tamoreton

Description

@tamoreton

Duplicate of github/secure_headers#348 but for helmet.

tl;dr Helmet sets upgrade-insecure-requests header by default. This is fine, but Safari honours that header even if the website is being served over HTTP, which means that if I'm doing local web development, assets (styles, scripts etc.) get upgraded to HTTPS and don't get loaded.

This behaviour is quite hard to reason about—I've encountered it a few times before and only just (with the help of this Stack Overflow thread) figured out why it's happening.

The current workaround is to put some branching in the consumer layer:

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: [
        "'self'",
        (req, res) => `'nonce-${res.locals.cspNonce}'`
      ],
      imgSrc: ["'self'"],
      connectSrc: ["'self'"],
      ...(process.env.NODE_ENV === 'development' && {
        upgradeInsecureRequests: null
      })
    }
  })
)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions