Giter Site home page Giter Site logo

getpagespeed / ngx_security_headers Goto Github PK

View Code? Open in Web Editor NEW
111.0 8.0 15.0 68 KB

NGINX Module for sending security headers

Home Page: https://www.getpagespeed.com/server-setup/nginx-security-headers-the-right-way

License: BSD 2-Clause "Simplified" License

C 80.94% Perl 19.06%
security nginx nginx-module x-frame-options x-powered-by securityheader https hsts hstspreload

ngx_security_headers's Introduction

ngx_security_headers

This NGINX module adds security headers and removes insecure headers, the right way (c).

Test Build

Synopsis

http {
    security_headers on;
    ...
}

Running curl -IL https://example.com/ will yield the added security headers:

HTTP/1.1 200 OK
Server: nginx
Date: Tue, 21 May 2019 16:15:46 GMT
Content-Type: text/html; charset=UTF-8
Vary: Accept-Encoding
Accept-Ranges: bytes
Connection: keep-alive
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Referrer-Policy: strict-origin-when-cross-origin
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

In general, the module features sending security HTTP headers in a way that better conforms to the standards. For instance, Strict-Transport-Security header should not be sent for plain HTTP requests. The module follows this recommendation.

Important note on Strict-Transport-Security

The module adds several security headers, including Strinct-Transport-Security. Note that preload is sent in the value of this header, by default. This means Chrome may and will include your websites to its preload list of domains which are HTTPS only.

It is usually what you want anyway, but bear in mind that in some edge cases you want to access a subdomain via plan unencrypted connection.

If you absolutely sure that all your domains and subdomains used with the module will ever primarily operate on HTTPs, proceed without any extra step.

If you are not sure if you have or will have a need to access your websites or any of its subdomains over plain insecure HTTP protocol, ensure security_headers_hsts_preload off; in your config before you ever start NGINX with the module to avoid having your domain preloaded by Chrome.

Key Features

  • Plug-n-Play: the default set of security headers can be enabled with security_headers on; in your NGINX configuration
  • Sends HTML-only security headers for relevant types only, not sending for others, e.g. X-Frame-Options is useless for CSS
  • Plays well with conditional GET requests: the security headers are not included there unnecessarily
  • Does not suffer the add_header directive's pitfalls
  • Hides X-Powered-By and other headers which often leak software version information
  • Hides Server header altogether, not just the version information

Configuration directives

security_headers

  • syntax: security_headers on | off
  • default: off
  • context: http, server, location

Enables or disables applying security headers. The default set includes:

  • X-Frame-Options: SAMEORIGIN
  • X-XSS-Protection: 0
  • Referrer-Policy: strict-origin-when-cross-origin
  • X-Content-Type-Options: nosniff

The values of these headers (or their inclusion) can be controlled with other security_headers_* directives below.

hide_server_tokens

  • syntax: hide_server_tokens on | off
  • default: off
  • context: http, server, location

Enables hiding headers which leak software information:

  • Server
  • X-Powered-By
  • X-Page-Speed
  • X-Varnish

It's worth noting that some of those headers bear functional use, e.g. X-Page-Speed docs mention:

... it is used to prevent infinite loops and unnecessary rewrites when PageSpeed fetches resources from an origin that also uses PageSpeed

So it's best to specify hide_server_tokens on; in a front-facing NGINX instances, e.g. the one being accessed by actual browsers, and not the ones consumed by Varnish or other software.

In most cases you will be just fine with security_headers on; and hide_server_tokens on;, without any adjustments.

For fine-tuning, use the header-specific directives below. A special value omit disables sending a particular header by the module (useful if you want to let your backend app to send it).

security_headers_xss

  • syntax: security_headers_xss off | on | block | omit
  • default: off
  • context: http, server, location

Controls X-XSS-Protection header. Special omit value will disable sending the header by the module. The off value is for disabling XSS protection: X-XSS-Protection: 0. This is the default because modern browsers do not support it and where it is supported, it introduces vulnerabilities.

security_headers_frame

  • syntax: security_headers_frame sameorigin | deny | omit
  • default: sameorigin
  • context: http, server, location

Controls inclusion and value of X-Frame-Options header. Special omit value will disable sending the header by the module.

security_headers_referrer_policy

  • syntax: security_headers_referrer_policy no-referrer | no-referrer-when-downgrade | same-origin | origin | strict-origin | origin-when-cross-origin | strict-origin-when-cross-origin | unsafe-url | omit
  • default: strict-origin-when-cross-origin
  • context: http, server, location

Controls inclusion and value of Referrer-Policy header. Special omit value will disable sending the header by the module.

Install

We highly recommend installing using packages, where available, instead of compiling.

CentOS/RHEL, Amazon Linux and Fedora packages

It's easy to install the module package for these operating systems.

ngx_security headers is part of the NGINX Extras collection, so you can install it alongside any modules, including PageSpeed and Brotli.

sudo yum -y install https://extras.getpagespeed.com/release-latest.rpm
sudo yum -y install nginx-module-security-headers

Then add it at the top of your nginx.conf:

load_module modules/ngx_http_security_headers_module.so;

In case you use ModSecurity NGINX module, make sure it's loaded last, like so:

load_module modules/ngx_http_security_headers_module.so;
load_module modules/ngx_http_modsecurity_module.so;

Other platforms

Compiling NGINX modules is prone to many problems, including making your website insecure. Be sure to keep your NGINX and modules updated, if you go that route.

To compile the module into NGINX, run:

./configure --with-compat --add-module=../ngx_security_headers
make 
make install

Or you can compile it as dynamic module. In that case, use --add-dynamic-module instead, and load the module after compilation by adding to nginx.conf:

load_module /path/to/ngx_http_security_headers_module.so;

ngx_security_headers's People

Contributors

alpha14 avatar dvershinin avatar jamesmacwhite avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ngx_security_headers's Issues

Header access control

While in-development, all hidden headers are good to be shown, e.g. #3 would hide caching headers, which need to be seen.

Need a method to bypass hiding based on IP/cookie/etc.

Strict-Transport-Security header not being added on SSL requests

NGINX 1.18.0

I tested this module out and while it did add all other security headers, the Strict-Transport-Security header was not output.

I have a server block defined with listen directives for SSL, configured with a valid LetsEncrypt certificate.

I can only assume this condition for whatever reason does not detect an SSL request.

https://github.com/GetPageSpeed/ngx_security_headers/blob/master/src/ngx_http_security_headers_module.c#L258-L265

nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 1.1.1f 31 Mar 2020
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-KTLRnK/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module

add custom header

Hi,

It's not security related, but would it be possible to insert the h3 svc header?
Or otherwise create a function to insert a custom header defined in nginx.conf?

Content-Security-Policy

Allow specifying CSP header using "free-form" string.
There is no one-suits everyone value.
The module should support setting it anyway, as this will eliminate having to have header-more module completely, in most setups.

Conflicts with ModSecurity

Just here to chime in and say that if you are using ModSecurity-nginx / ModSecurity (v3), there is a conflict and you'd see errors like this in nginx error log. The module itself doesn't cause this, but I had the directive security_headers on; which caused this. Haven't tested with other directives. Hope this helps anyone coming across this one. Difficult to find.

2019/08/20 19:56:31 [alert] 2957#2957: worker process 2980 exited on signal 6
terminate called after throwing an instance of 'std::bad_alloc'

Strict-Transport-Security: Preloading doesn't work

First of all, thank you for this module. I'm using it on all of my servers with succes.
I did a fresh git pull. Unfortunately, preload doesn't work.

Configure flags:

nginx version: nginx/1.21.6
built by gcc 8.3.0 (Debian 8.3.0-6) 
built with OpenSSL 3.0.2 15 Mar 2022
TLS SNI support enabled
configure arguments: --prefix=/opt/nginx --user=www-data --group=www-data --with-http_v2_module --with-http_ssl_module --with-http_v2_hpack_enc --with-pcre-jit --with-file-aio --with-http_flv_module --with-http_geoip_module --with-http_gunzip_module --with-http_mp4_module --with-http_realip_module --with-http_stub_status_module --with-threads --with-libatomic --with-zlib=/usr/local/src/zlib --with-zlib-opt='-O3 -march=native -flto -fuse-linker-plugin' --with-http_gzip_static_module --with-openssl=/usr/local/src/openssl-3.0.2 --with-openssl-opt='no-zlib enable-rfc3779 enable-ec_nistp_64_gcc_128 no-tests no-unit-test -DCFLAGS=-O3 -march=native -flto -fuse-linker-plugin' --add-module=/usr/local/src/headers-more-nginx-module --add-module=/usr/local/src/echo-nginx-module --add-module=/usr/local/src/ngx_http_substitutions_filter_module --add-module=/usr/local/src/srcache-nginx-module --add-module=/usr/local/src/redis2-nginx-module --add-module=/usr/local/src/ngx_http_redis-0.3.9 --add-module=/usr/local/src/ngx_devel_kit --add-module=/usr/local/src/set-misc-nginx-module --add-module=/usr/local/src/ngx_brotli --add-module=/usr/local/src/ngx_security_headers --add-module=/usr/local/src/ngx_immutable --with-cc-opt='-DTCP_FASTOPEN=23 -march=native -flto -O3 -fuse-linker-plugin -Wno-error=strict-aliasing -fstack-protector-strong -D_FORTIFY_SOURCE=2' --with-ld-opt='-lrt -z relro -fstack-protector-strong'

In the nginx config I added security_headers on; in the main http block.

Header output:

❯ curl --compressed -IL "https://www.weblogzwolle.nl/"
HTTP/2 200 
server: nginx
date: Wed, 16 Mar 2022 21:20:51 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
set-cookie: wordpress_test_cookie=WP%20Cookie%20check; path=/
link: <https://www.weblogzwolle.nl/wp-json/>; rel="https://api.w.org/"
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
strict-transport-security: max-age=63072000; includeSubDomains
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
x-cache: HIT
x-cache-2: BYPASS
public-key-pins: pin-sha256="fAYmhNNLaXs7XP8rVh/3+nACEdZefovkCJt8cZQFcDQ="; pin-sha256="C8AGueBZ5S3lFTVCU+/S3Fteku3NGRa0MHkeMsjvAKk="; pin-sha256="6tMzCDSUXMz7f8wecFye+mg5jgw7125rFQFODpx49xc="; pin-sha256="d4ilv6cF8gYda+qqKSdDulWJR7nfZdt1M6Hi/494i9Y="; max-age=5184000; report-uri="https://hansvaneijsden.report-uri.com/r/d/hpkp/enforce";
content-security-policy: upgrade-insecure-requests
expect-ct: enforce,max-age=604800
content-encoding: br

System:

❯ uname -a
Linux vps 5.10.0-0.bpo.11-amd64 #1 SMP Debian 5.10.92-1~bpo10+1 (2022-02-03) x86_64 GNU/Linux

I have this problem on all of my servers and vhosts.
What am I doing wrong? Please let me know if you need more information, I'm happy to provide it.

Missing ".configure" file for compiling on Ubuntu

The compile on other platforms module states the following:

./configure --with-compat --add-module=../ngx_security_headers
make 
make install

However, I am trying to compile this module on Ubuntu Server, but there is no .configure file in the root directory, so the ./configure --with-compat --add-module=../ngx_security_headers command doesn't work. How am I supposed to configure this module and compile it? Please help.

Rewrite Referrer-Policy header

How about, before anything else this module is great.

Is there any way to overwrite the Referrer-Policy header?

I have seen that this module adds the header with the default "no-referrer-when-downgrade" and if I add the add_header instruction with the value "no-referrer" two headers with different values are added.

Hide cache headers

Cachability that is exposed via HTTP headers, is a security risk.

URLs which are found to be uncacheable all the time through those headers pose a threat
of denial of service against them.

List of common cachability headers:

  • x-varnish
  • x-cache
  • x-cache-hits
  • x-cache-status (so essentially x-cache*)

Not able to install through yum.

Hi.
I'm not able to install it using yum although yum is working on my server. it says unable to open....
is there any other way i can download and install the module.
thanks logs are below:
sudo yum -y install https://extras.getpagespeed.com/release-latest.rpm
Failed to set locale, defaulting to C
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Cannot open: https://extras.getpagespeed.com/release-latest.rpm. Skipping.
Error: Nothing to do

Strict-Transport-Security: Preloading should be opt-in

It's potentially dangerous for the default to include preload in the header, because of any misconfiguration or mistake. If a browser adds a domain into the preload list without the proper configuration or requirements, that domain will be broken, unless removed from the preload list which can take time and is a manual process.

https://hstspreload.org/#opt-in

Having preload added to the header should be an opt-in setting, rather than hard coded into the module by default. It also doesn't make sense for an nginx server that may just serving subdomains. The preload value would only apply on the root domain.

How to use it on Windows's nginx?

I'm using a Windows server with nginx and I want to use this to hide nginx in header. It appears I need to compile nginx with this module which seems to be quite complicated. Is there any released binary that I can use it easily?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.