{"id":18926072,"url":"https://github.com/getpagespeed/ngx_security_headers","last_synced_at":"2026-02-15T13:03:20.347Z","repository":{"id":40988541,"uuid":"168027028","full_name":"GetPageSpeed/ngx_security_headers","owner":"GetPageSpeed","description":"NGINX Module for sending security headers","archived":false,"fork":false,"pushed_at":"2026-02-03T10:58:03.000Z","size":62,"stargazers_count":121,"open_issues_count":5,"forks_count":22,"subscribers_count":5,"default_branch":"master","last_synced_at":"2026-02-03T23:50:33.888Z","etag":null,"topics":["hsts","hstspreload","https","nginx","nginx-module","security","securityheader","x-frame-options","x-powered-by"],"latest_commit_sha":null,"homepage":"https://www.getpagespeed.com/server-setup/nginx-security-headers-the-right-way","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GetPageSpeed.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"GetPageSpeed","patreon":"getpagespeed","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2019-01-28T19:56:20.000Z","updated_at":"2026-02-03T10:56:38.000Z","dependencies_parsed_at":"2024-12-16T03:06:57.357Z","dependency_job_id":"8c8a451e-ac38-4481-98fb-93cb78eda9f4","html_url":"https://github.com/GetPageSpeed/ngx_security_headers","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/GetPageSpeed/ngx_security_headers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx_security_headers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx_security_headers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx_security_headers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx_security_headers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GetPageSpeed","download_url":"https://codeload.github.com/GetPageSpeed/ngx_security_headers/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GetPageSpeed%2Fngx_security_headers/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29478906,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-15T11:35:25.641Z","status":"ssl_error","status_checked_at":"2026-02-15T11:34:57.128Z","response_time":118,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hsts","hstspreload","https","nginx","nginx-module","security","securityheader","x-frame-options","x-powered-by"],"created_at":"2024-11-08T11:14:26.739Z","updated_at":"2026-02-15T13:03:20.343Z","avatar_url":"https://github.com/GetPageSpeed.png","language":"C","readme":"# ngx_security_headers\n\nThis NGINX module adds security headers and removes insecure headers, *the right way* (c). \n\n[![Test Build](https://github.com/GetPageSpeed/ngx_security_headers/actions/workflows/build.yml/badge.svg?event=push)](https://github.com/GetPageSpeed/ngx_security_headers/actions/workflows/build.yml)\n\n## Synopsis\n\n```nginx\nhttp {\n    security_headers on;\n    ...\n}\n```\n\nRunning `curl -IL https://example.com/` will yield the added security headers:\n\n\u003cpre\u003e\nHTTP/1.1 200 OK\nServer: nginx\nDate: Tue, 21 May 2019 16:15:46 GMT\nContent-Type: text/html; charset=UTF-8\nVary: Accept-Encoding\nAccept-Ranges: bytes\nConnection: keep-alive\n\u003cb\u003eX-Frame-Options: SAMEORIGIN\nX-Content-Type-Options: nosniff\nReferrer-Policy: strict-origin-when-cross-origin\nCross-Origin-Resource-Policy: same-site\nStrict-Transport-Security: max-age=31536000; includeSubDomains; preload\u003c/b\u003e\n\u003c/pre\u003e\n\nIn general, the module features sending security HTTP headers in a way that better conforms to the standards.\nFor instance, `Strict-Transport-Security` header should *not* be sent for plain HTTP requests.\nThe module follows this recommendation.\n\n## Important note on `Strict-Transport-Security`\n\nThe module adds several security headers, including `Strinct-Transport-Security`.\nNote that `preload` is sent in the value of this header, by default.\nThis means Chrome may and will include your websites to its preload list of domains which are HTTPS only.\n\nIt is *usually* what you want anyway, but bear in mind that in some edge cases you want to access\na subdomain via plan unencrypted connection.\n\nIf you absolutely sure that all your domains and subdomains used with the module will ever primarily operate\non HTTPs, proceed without any extra step.\n\nIf you are *not sure* if you have or will have a need to access your websites or any of its subdomains over\nplain insecure HTTP protocol, ensure `security_headers_hsts_preload off;` in your config before you ever\nstart NGINX with the module to avoid having your domain preloaded by Chrome.\n\n## Key Features\n\n*   Plug-n-Play: the default set of security headers can be enabled with `security_headers on;` in your NGINX configuration\n*   Sends HTML-only security headers for relevant types only, not sending for others, e.g. `X-Frame-Options` is useless for CSS\n*   Plays well with conditional `GET` requests: the security headers are not included there unnecessarily\n*   Does not suffer the `add_header` directive's pitfalls\n*   Hides `X-Powered-By` and other headers which often leak software version information\n*   Hides `Server` header altogether, not just the version information\n\n## Configuration directives\n\n### `security_headers`\n\n- **syntax**: `security_headers on | off`\n- **default**: `off`\n- **context**: `http`, `server`, `location`\n\nEnables or disables applying security headers. The default set includes:\n\n* `X-Frame-Options: SAMEORIGIN`\n* `Referrer-Policy: strict-origin-when-cross-origin`\n* `X-Content-Type-Options: nosniff`\n* `Cross-Origin-Resource-Policy: same-site`\n\nThe deprecated `X-XSS-Protection` header is actively removed by default.\n\nThe values of these headers (or their inclusion) can be controlled with other `security_headers_*` directives below.\n\n### `hide_server_tokens`\n\n- **syntax**: `hide_server_tokens on | off`\n- **default**: `off`\n- **context**: `http`, `server`, `location`\n\nEnables hiding headers which leak software information:\n\n*   `Server`\n*   `X-Powered-By`\n*   `X-Page-Speed`\n*   `X-Varnish`\n\nIt's worth noting that some of those headers bear functional use, e.g. [`X-Page-Speed` docs](https://www.modpagespeed.com/doc/configuration#XHeaderValue) mention:\n\n\u003e ... it is used to prevent infinite loops and unnecessary rewrites when PageSpeed \n\u003e fetches resources from an origin that also uses PageSpeed\n\nSo it's best to specify `hide_server_tokens on;` in a front-facing NGINX instances, e.g.\nthe one being accessed by actual browsers, and not the ones consumed by Varnish or other software.\n\nIn most cases you will be just fine with `security_headers on;` and `hide_server_tokens on;`, without any adjustments.\n\nFor fine-tuning, use the header-specific directives below. \nA special value `omit` disables sending a particular header by the module (useful if you want to let your backend app to send it). \n\n### `security_headers_xss`\n\n- **syntax**: `security_headers_xss off | on | block | omit | unset`\n- **default**: `unset`\n- **context**: `http`, `server`, `location`\n\nControls `X-XSS-Protection` header.\n\n* `unset` (default): Actively removes the header from responses, including any set by upstream servers. This is the recommended setting because the header is deprecated and [introduces XSS vulnerabilities](https://github.com/nicosalm/security-lab-xss-filter) in browsers that support it.\n* `omit`: Does not add or remove the header; allows upstream headers through unchanged.\n* `off`: Sends `X-XSS-Protection: 0` to explicitly disable browser XSS filtering.\n* `on`: Sends `X-XSS-Protection: 1`.\n* `block`: Sends `X-XSS-Protection: 1; mode=block`.\n\n### `security_headers_frame`\n\n- **syntax**: `security_headers_frame sameorigin | deny | omit`\n- **default**: `sameorigin`\n- **context**: `http`, `server`, `location`\n\nControls inclusion and value of `X-Frame-Options` header. \nSpecial `omit` value will disable sending the header by the module. \n\n\n### `security_headers_referrer_policy`\n\n- **syntax**: `security_headers_referrer_policy no-referrer | no-referrer-when-downgrade | same-origin | origin \n| strict-origin | origin-when-cross-origin | strict-origin-when-cross-origin | unsafe-url | omit`\n- **default**: `strict-origin-when-cross-origin`\n- **context**: `http`, `server`, `location`\n\nControls inclusion and value of [`Referrer-Policy`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) header.\nSpecial `omit` value will disable sending the header by the module.\n\n### `security_headers_corp`\n\n- **syntax**: `security_headers_corp same-site | same-origin | cross-origin | omit`\n- **default**: `same-site`\n- **context**: `http`, `server`, `location`\n\nControls inclusion and value of [`Cross-Origin-Resource-Policy`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy) header.\nThis header controls how your resources can be embedded by other origins.\nSpecial `omit` value will disable sending the header by the module.\n\nThe default `same-site` is a safe choice that prevents cross-site embedding while allowing same-site requests.\n\n### `security_headers_coop`\n\n- **syntax**: `security_headers_coop same-origin | same-origin-allow-popups | unsafe-none | omit`\n- **default**: `omit`\n- **context**: `http`, `server`, `location`\n\nControls inclusion and value of [`Cross-Origin-Opener-Policy`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy) header.\nThis header controls window opener relationships across origins.\nSpecial `omit` value will disable sending the header by the module.\n\nThe default is `omit` because enabling this header can break popup/window.opener communication patterns.\nEnable explicitly only if you understand the implications.\n\n### `security_headers_coep`\n\n- **syntax**: `security_headers_coep require-corp | credentialless | unsafe-none | omit`\n- **default**: `omit`\n- **context**: `http`, `server`, `location`\n\nControls inclusion and value of [`Cross-Origin-Embedder-Policy`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy) header.\nThis header controls embedding of cross-origin resources.\nSpecial `omit` value will disable sending the header by the module.\n\nThe default is `omit` because enabling this header can break sites that load third-party resources\n(analytics, CDN assets, ads) without proper CORS headers.\n\n### Cross-Origin Isolation\n\nTo enable [cross-origin isolation](https://web.dev/cross-origin-isolation-guide/) (required for `SharedArrayBuffer` and high-resolution timers),\nconfigure all three cross-origin headers:\n\n```nginx\nsecurity_headers on;\nsecurity_headers_corp same-origin;\nsecurity_headers_coop same-origin;\nsecurity_headers_coep require-corp;\n```\n\n**Warning**: This configuration will break loading of any cross-origin resources that don't explicitly allow it via CORS.\n\n## Install\n\nWe highly recommend installing using packages, where available,\ninstead of compiling.\n\n### Ubuntu and Debian packages\n\nIt's easy to install the module package for these operating systems.\n\n`ngx_security headers` is part of the APT NGINX Extras collection, so you can install\nit alongside [any modules](https://apt-nginx-extras.getpagespeed.com/modules/), \nincluding Brotli.\n\nFirst, [set up the repository](https://apt-nginx-extras.getpagespeed.com/apt-setup/), then:\n\n```bash\nsudo apt-get update\nsudo apt-get install nginx-module-security-headers\n```\n\n### CentOS/RHEL, Amazon Linux and Fedora packages\n\nIt's easy to install the module package for these operating systems.\n\n`ngx_security headers` is part of the NGINX Extras collection, so you can install\nit alongside [any modules](https://nginx-extras.getpagespeed.com/), \nincluding PageSpeed and Brotli.\n\n```bash\nsudo yum -y install https://extras.getpagespeed.com/release-latest.rpm\nsudo yum -y install nginx-module-security-headers\n```\n\n\nThen add it at the top of your `nginx.conf`:\n\n```nginx\nload_module modules/ngx_http_security_headers_module.so;\n```\n    \nIn case you use ModSecurity NGINX module, make sure it's loaded last, like so:\n\n```nginx\nload_module modules/ngx_http_security_headers_module.so;\nload_module modules/ngx_http_modsecurity_module.so;\n```\n\n### Other platforms\n\nCompiling NGINX modules is [prone to many problems](https://www.getpagespeed.com/server-setup/where-compilation-went-wrong), \nincluding making your website insecure. Be sure to keep your NGINX and modules updated, if you go that route.\n\nTo compile the module into NGINX, run:\n\n```bash\n./configure --with-compat --add-module=../ngx_security_headers\nmake \nmake install\n```\n\nOr you can compile it as dynamic module. In that case, use `--add-dynamic-module` instead, and load the module after \ncompilation by adding to `nginx.conf`:\n\n```nginx\nload_module /path/to/ngx_http_security_headers_module.so;\n```\n","funding_links":["https://github.com/sponsors/GetPageSpeed","https://patreon.com/getpagespeed"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetpagespeed%2Fngx_security_headers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetpagespeed%2Fngx_security_headers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetpagespeed%2Fngx_security_headers/lists"}