Opened 13 months ago

Last modified 13 months ago

#1083 new enhancement

Enable gzip compression only for non "text/html" content

Reported by: sustmi@… Owned by:
Priority: minor Milestone:
Component: nginx-module Version: 1.11.x
Keywords: gzip gzip_types html Cc:
Sensitive: no
uname -a:
nginx -V: nginx version: nginx/1.10.1 built by gcc 6.1.1 20160510 (Red Hat 6.1.1-2) (GCC) built with OpenSSL 1.0.2h-fips 3 May 2016 TLS SNI support enabled configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'

Description

I want to enable gzip HTTP (ngx_http_gzip_module) compression but only for static content (JS, CSS) and not for HTML.

HTTP compression can be exploited by BREACH or HEIST attacks. These attacks makes it possible to "guess" SSL encrypted secrets when the content is compressed.

Therefore I want to compress only the content that:

  1. does not change on user input (attackers guess) and hence mitigates the possibility to use the attack,
  2. does not contain any sensitive data (JS and CSS are public for anyone).

However according to the documentation:
"Responses with the “text/html” type are _always_ compressed."
(see http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_types )

This means that even when I set "gzip_types" to "application/javascript text/css" I automatically enable attackers to guess any sensitive/secret data contained in HTML (eg. email, credit card number, session ID in hyper-links, CSRF tokens).

Can you make it possible to enable gzip compression only on certain supplied MIME types but not "text/html" (unless it is on the list too)?

Something like "gzip_force_default_types" setting that is "on" by default to keep backwards compatibility.

Change History (2)

comment:1 Changed 13 months ago by sustmi@…

I'll write a patch for this if you do not think it is a bad idea. :)

comment:2 Changed 13 months ago by sustmi@…

I am struggling with the Nginx code base a bit (I did not program in C for several years), but hopefully the patch will be ready soon (in few days). :)

In meantime, I found a workaround. Luckily we have all the static content under the same directory (directory static in document root) so I just added a sub location that allows gzip only in specified directory:

location / {
  gzip off;

  try_files $url @app;

  location /static/ {
    gzip on;
    gzip_types application/javascript text/css;
  }

  # ...
}
Note: See TracTickets for help on using tickets.