diff --git a/content/faq/_index.md b/content/faq/_index.md index daa2284..04097cb 100644 --- a/content/faq/_index.md +++ b/content/faq/_index.md @@ -10,4 +10,5 @@ title: "Frequently asked questions (FAQ)" - [How do I upgrade from Helmet 3 to Helmet 4?]({{< ref "faq/helmet-4-upgrade" >}}) - [How do I set a Content Security Policy nonce?]({{< ref "faq/csp-nonce-example" >}}) - [How do I set both `Content-Security-Policy` and `Content-Security-Policy-Report-Only` headers?](https://github.com/helmetjs/helmet/issues/351#issuecomment-1015498560) +- [How should I use Helmet with non-document responses?]({{< ref "faq/non-documents" >}}) - [Who made Helmet?]({{< ref "faq/contributors" >}}) diff --git a/content/faq/non-documents.md b/content/faq/non-documents.md new file mode 100644 index 0000000..0d572ef --- /dev/null +++ b/content/faq/non-documents.md @@ -0,0 +1,50 @@ +--- +title: "How should I use Helmet with non-document responses?" +--- + +Helmet is designed to be easy to use. It sets its security headers for all responses. + +Unfortunately, this can lead to unnecessarily headers being set for some responses, hampering performance slightly. For example, you don't need to set the `Content-Security-Policy` header when responding with a PNG image, but you probably _do_ want to set the `Strict-Transport-Security` header. + +Here is a list of Helmet headers that are *usually safe to omit unless you're responding with HTML*: + +- `Content-Security-Policy` +- `Cross-Origin-Embedder-Policy` +- `Cross-Origin-Opener-Policy` +- `Origin-Agent-Cluster` +- `Referrer-Policy` +- `X-DNS-Prefetch-Control` +- `X-XSS-Protection` + +This all depends on your application, though. **If you're not sure, keep the header.** + +There are a wide variety of options to address this issue and they are heavily dependent on your application, so it's hard to give a code snippet. But here's a very naïve one: + +```javascript +const helmetForDocuments = helmet(); +const helmetForNonDocuments = helmet({ + contentSecurityPolicy: false, + crossOriginEmbedderPolicy: false, + crossOriginOpenerPolicy: false, + originAgentCluster: false, + referrerPolicy: false, + xDnsPrefetchControl: false, + xXssProtection: false, +}); + +// ... + +app.get( + "/my/route", + (req, res, next) => { + if (shouldRespondWithDocument(req)) { + helmetForDocuments(req, res, next); + } else { + helmetForNonDocuments(req, res, next); + } + }, + (req, res) => { + // ... + }, +); +```