{"id":17103,"library":"hpkp","title":"HTTP Public Key Pinning (HPKP) middleware","description":"The `hpkp` package provides HTTP Public Key Pinning (HPKP) middleware for Express and Connect applications. It facilitates adding the `Public-Key-Pins` or `Public-Key-Pins-Report-Only` headers to web responses, which allows sites to declare cryptographic identities for web servers. However, HPKP as a security standard has been widely deprecated by browser vendors, including Chrome, due to significant risks of misuse and the potential for self-inflicted denial-of-service by rendering a website permanently inaccessible to legitimate users. The package is currently at version 3.0.0 and is explicitly in maintenance mode, indicating it will not receive new feature development but will be maintained for critical bug fixes. Developers are strongly advised against implementing HPKP in new projects and should consider alternatives like Certificate Transparency and Expect-CT headers.","status":"deprecated","version":"3.0.0","language":"javascript","source_language":"en","source_url":"git://github.com/helmetjs/hpkp","tags":["javascript","hpkp","public key pinning"],"install":[{"cmd":"npm install hpkp","lang":"bash","label":"npm"},{"cmd":"yarn add hpkp","lang":"bash","label":"yarn"},{"cmd":"pnpm add hpkp","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The `hpkp` package exports the middleware function as its default export.","wrong":"import { hpkp } from 'hpkp'","symbol":"hpkp","correct":"import hpkp from 'hpkp'"},{"note":"CommonJS import for Node.js environments. This is shown in the official usage example.","symbol":"hpkp","correct":"const hpkp = require('hpkp')"},{"note":"If using TypeScript, `HpkpOptions` is the interface for the configuration object passed to the `hpkp` middleware. Use `import type` as it's a type-only import.","wrong":"import { HpkpOptions } from 'hpkp'","symbol":"HpkpOptions","correct":"import type { HpkpOptions } from 'hpkp'"}],"quickstart":{"code":"const express = require(\"express\");\nconst hpkp = require(\"hpkp\");\n\nconst app = express();\n\nconst ninetyDaysInSeconds = 7776000; // 90 days\napp.use(\n  hpkp({\n    maxAge: ninetyDaysInSeconds,\n    sha256s: [\n      // These should be your actual SPKI hashes for primary and backup keys\n      \"AbCdEf123=\", \n      \"ZyXwVu456=\" \n    ],\n    includeSubDomains: true, // optional\n    reportUri: \"https://example.com/hpkp-report\", // optional\n    reportOnly: false, // optional, set to true for testing\n\n    // Set the header based on a condition. This is optional.\n    setIf(req, res) {\n      return req.secure; // Only set HPKP for HTTPS requests\n    },\n  }),\n);\n\napp.get('/', (req, res) => {\n  res.send('HPKP header should be set if using HTTPS');\n});\n\napp.listen(3000, () => {\n  console.log('Server running on port 3000');\n  console.log('Remember HPKP is deprecated and risky. Use with extreme caution.');\n});","lang":"javascript","description":"This quickstart demonstrates how to integrate the `hpkp` middleware into an Express.js application, setting a Public Key Pinning header with example SHA256 hashes and optional configurations. It highlights the use of `maxAge`, `sha256s`, and conditional header setting via `setIf`."},"warnings":[{"fix":"Avoid using HPKP in new applications. For existing applications, strongly consider migrating to alternative security mechanisms like Certificate Transparency and Expect-CT headers, which offer similar protections with fewer risks.","message":"The HTTP Public Key Pinning (HPKP) standard itself has been widely deprecated by browser vendors, including Chrome, due to its inherent risks and potential for website self-DDoS.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Always use `reportOnly: true` and a very short `maxAge` (e.g., 60 seconds) during initial deployment and testing. Ensure robust processes for key rotation and backup key management. Never deploy HPKP without a verified fallback strategy for pin mismatches.","message":"Misconfiguration of HPKP, particularly incorrect `sha256s` or loss of access to pinned keys, can permanently block legitimate users from accessing your website, as their browsers will refuse connections.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Consider that the underlying technology is no longer actively developed or recommended. If you must use it, be aware of its static nature and potential for obsolescence.","message":"The `hpkp` package is in maintenance mode and will not receive new feature development. This means it may not adapt to future security best practices or changes in related web standards.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Ensure that the provided hashes are correctly derived from the SPKI of your active and backup certificates, and are properly Base64 encoded. Tools are available to generate these from certificate files.","message":"The `sha256s` array must contain Base64-encoded Subject Public Key Information (SPKI) fingerprints. Using incorrect hash formats or non-SPKI hashes will lead to pinning failures.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Before deploying, understand that the impact of HPKP will be limited to older or specific browser versions that still honor the header. The security benefits are minimal given current browser landscape.","message":"Browser support for HPKP is inconsistent and has been largely removed. Modern browsers like Chrome have dropped support, rendering the header ineffective for many users.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"During testing, verify `sha256s` values. If in production, and users are locked out, you must either deploy a certificate matching one of the original pinned keys, or if no backup key is available, wait for `maxAge` to expire (which could be months). Using `reportOnly: true` initially can help avoid this.","cause":"The public key pins declared in the `Public-Key-Pins` HTTP header do not match the public key of the server's certificate presented during a TLS handshake.","error":"NET::ERR_SSL_PINNING_FAILURE"},{"fix":"Ensure the `hpkp` middleware is applied before any routes that should be protected. Check your `setIf` function's logic to confirm it evaluates to `true` for the requests you intend to pin. Verify that `maxAge` is a positive integer.","cause":"The `hpkp` middleware might be placed incorrectly in the middleware chain, or the `setIf` option is preventing it from being applied under current request conditions (e.g., not an HTTPS request).","error":"My HPKP header isn't being set on my Express/Connect application."}],"ecosystem":"npm","meta_description":null}