{"id":16055,"library":"hsts","title":"HTTP Strict Transport Security (HSTS) Middleware","description":"The `hsts` package provides HTTP Strict Transport Security (HSTS) middleware for Node.js applications, primarily for use with Express or Connect. It adds the `Strict-Transport-Security` header to HTTP responses, instructing browsers to interact with the site exclusively over HTTPS for a specified duration. Key features include configurable `maxAge` (in seconds), `includeSubDomains`, and `preload` directives for HSTS preloading services. This package is part of the Helmet.js suite, a collection of security middleware. The current stable version is 2.2.0, which has been stable for some time, indicating a mature, maintenance-oriented release cadence rather than frequent updates unless security vulnerabilities or major breaking changes in web standards require it. Its primary differentiator is its simplicity and integration within the widely adopted Helmet.js ecosystem, ensuring robust and standard-compliant HSTS implementation.","status":"active","version":"2.2.0","language":"javascript","source_language":"en","source_url":"git://github.com/helmetjs/hsts","tags":["javascript","helmet","security","express","connect","hsts","https"],"install":[{"cmd":"npm install hsts","lang":"bash","label":"npm"},{"cmd":"yarn add hsts","lang":"bash","label":"yarn"},{"cmd":"pnpm add hsts","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"ESM import for modern Node.js environments. For older CommonJS projects, use `const hsts = require('hsts')`.","wrong":"const hsts = require('hsts')","symbol":"hsts","correct":"import hsts from 'hsts'"},{"note":"The default export is a function that returns the middleware. It's often assigned to a variable for conditional use.","symbol":"hstsMiddleware","correct":"import hsts from 'hsts'; const hstsMiddleware = hsts({...});"}],"quickstart":{"code":"import express from 'express';\nimport hsts from 'hsts';\n\nconst app = express();\nconst port = process.env.PORT || 3000;\n\n// Basic HSTS configuration for 180 days, including subdomains\napp.use(hsts({\n  maxAge: 15552000, // 180 days in seconds\n  includeSubDomains: true\n}));\n\n// Advanced configuration with preload for HSTS preloading services\n// Requires maxAge to be at least 1 year (31536000 seconds) and includeSubDomains to be true.\nconst preloadHstsMiddleware = hsts({\n  maxAge: 31536000, // 1 year\n  includeSubDomains: true,\n  preload: true\n});\n\n// Conditionally apply HSTS middleware only on secure requests\napp.use((req, res, next) => {\n  if (req.secure) {\n    preloadHstsMiddleware(req, res, next);\n  } else {\n    next();\n  }\n});\n\napp.get('/', (req, res) => {\n  res.send('Hello HSTS World!');\n});\n\napp.listen(port, () => {\n  console.log(`Server listening on port ${port}. Ensure you access via HTTPS to see HSTS headers.`);\n});","lang":"typescript","description":"Demonstrates basic and conditional HSTS middleware setup for an Express application, including options for preloading."},"warnings":[{"fix":"Always provide the `maxAge` value in seconds. For example, `15552000` for 180 days.","message":"The `maxAge` option in `hsts` middleware now requires the value to be specified in seconds. In previous versions, different units might have been accepted.","severity":"breaking","affected_versions":"<2.0.0"},{"fix":"Consider applying the HSTS middleware conditionally, only for requests that are already secure (`req.secure`). You might also need a separate mechanism like `express-enforces-ssl` to redirect HTTP traffic to HTTPS.","message":"The `Strict-Transport-Security` header is ignored by browsers when served over insecure HTTP connections (e.g., `http://`). It will only be processed if the initial request is HTTPS.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"When using `preload: true`, ensure `maxAge` is `31536000` or higher and `includeSubDomains` is `true`.","message":"To be eligible for HSTS preloading services (e.g., `hstspreload.org`), specific criteria must be met, including `maxAge` being at least one year (31536000 seconds) and `includeSubDomains` being enabled.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Implement a separate redirect mechanism (e.g., using `express-enforces-ssl` or custom middleware) to redirect all incoming HTTP traffic to HTTPS before the HSTS middleware is applied.","message":"HSTS only tells browsers to *stick* to HTTPS after an initial secure connection. It does not enforce a switch from HTTP to HTTPS for initial unsecure requests. Browsers will simply ignore the header on HTTP.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure your application is served over HTTPS. Use a tool like `ngrok` or a local proxy for development, or deploy to an environment with SSL/TLS enabled for testing.","cause":"The HSTS header is only sent and processed by browsers when the connection is secure (HTTPS). If you're testing on HTTP, the browser will ignore it.","error":"Strict-Transport-Security header not appearing on my site."},{"fix":"Double-check your `maxAge` calculation. For example, 180 days is 180 * 24 * 60 * 60 = 15,552,000 seconds. A common long-term value is 31,536,000 for one year.","cause":"The `maxAge` value must be specified in seconds. Incorrect conversion from days/weeks/years to seconds is a common mistake.","error":"HSTS maxAge seems too short or incorrect."},{"fix":"Ensure your HSTS middleware is configured with `maxAge: 31536000` (at least 1 year), `includeSubDomains: true`, and `preload: true`. Verify the header is correctly served via HTTPS.","cause":"HSTS preload services have strict requirements for the header, including a minimum `maxAge` and the presence of `includeSubDomains` and `preload` directives.","error":"Cannot submit my site to hstspreload.org."}],"ecosystem":"npm"}