Skip to content

nginx reverse proxy strips response headers from backend #735

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pwyliu opened this issue Jun 4, 2014 · 13 comments
Closed

nginx reverse proxy strips response headers from backend #735

pwyliu opened this issue Jun 4, 2014 · 13 comments

Comments

@pwyliu
Copy link

pwyliu commented Jun 4, 2014

In a set up like this:

(client) <--> (nginx+modsec reverse proxy) <--> (backend web server)

If the backend server adds a new response header, modsec doesn't pass it to the client.

This happens even if all the rules are disabled and SecRuleEngine Off is set. It seems anything new that is added by the backend will get dropped.

We noticed this because we were trying to byte serve a PDF from the backend. Chrome uses range requests, but modsec drops the Content-Range header from the response, so it makes the client download the file forever.

I set up a super tiny test environment with nginx 1.6.0 and modsec 2.8.0 and could recreate the issue there. Here is a gist with some logs and the configs. We also saw this in another similar set up which was nginx 1.4.4 and modsec 2.7.7.

I hope I didn't miss anything, please let me know if any more info is needed.

@rmongia
Copy link

rmongia commented Jun 27, 2014

I am facing the same issue. The culprit commit seems to be this one: 177b5b9.

@scaarup
Copy link

scaarup commented Jul 3, 2014

I am also facing this problem. We are adding a custom header to the response on the backend-servers. But this never returns to the client.

@scaarup
Copy link

scaarup commented Jul 11, 2014

And one important header "Content-Type" is not passed - this breaks our applications...

zimmerle pushed a commit that referenced this issue Jul 28, 2014
@scaarup
Copy link

scaarup commented Aug 4, 2014

@zimmerle I have tried your fix, but with no luck...

@rmongia
Copy link

rmongia commented Aug 4, 2014

@scaarup, can you tell me the response headers with and without ModSecurity in play.

@scaarup
Copy link

scaarup commented Aug 6, 2014

@zimmerle, yes here they are, first with modsecurity and then without. It is actually only content-type which is missing. X-Server-Name and Jokum are custom header fields provided by the apache upstream. So something is working.

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 06 Aug 2014 06:06:42 GMT
Connection: keep-alive
Set-Cookie: PMLCID=192%2E168%2E11%2E125%2E30211140730519; expires=Fri, 05-Sep-14 06:06:33 GMT;path=/; secure; HttpOnly
Set-Cookie: PMLSID=192%2E168%2E11%2E125%2E30211140730519; path=/; secure; HttpOnly
X-Server-Name: server11
Jokum: server11
Content-Length: 559148

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 06 Aug 2014 06:07:19 GMT
Content-Type: text/html
Connection: keep-alive
Set-Cookie: PMLCID=192%2E168%2E11%2E125%2E302531407305239; expires=Fri, 05-Sep-14 06:07:19 GMT;path=/; secure; HttpOnly
Set-Cookie: PMLSID=192%2E168%2E11%2E125%2E302531407305239; path=/; secure; HttpOnly
X-Server-Name: server11
Jokum: server11
Content-Length: 559148

@ZaleskiR
Copy link

ZaleskiR commented Aug 7, 2014

I found inside of ngx_http_modsecurity.c, ngx_http_clean_header(r) is called, which deletes all of the output headers. Not sure why this is done, but commenting it out fixes the problem.

static ngx_inline ngx_int_t
ngx_http_modsecurity_save_headers_out(ngx_http_request_t *r)
{
ngx_http_modsecurity_ctx_t *ctx;
ngx_http_upstream_t *upstream;

ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);

/* r->chunked = ctx->req->chunked; */

// WHY ARE HEADERS OUT BEING DELETED?
//// ngx_http_clean_header(r);

upstream = r->upstream;
r->upstream = &ngx_http_modsecurity_upstream;

@rmongia
Copy link

rmongia commented Aug 8, 2014

@scaarup, the fix was for ModSecurity + nginx. It won't impact your setup.

@ZaleskiR, you can try the patch for ModSecurity Nginx module provided here to solve response headers problem. Commenting the ngx_http_clean_header() will work fine with DetectionOnly mode but with ModSecurity Engine ON, it would require this code to be there to sanitize the response.

@scaarup
Copy link

scaarup commented Aug 11, 2014

@rmongia I am using ModSecurity + nginx...

@rmongia
Copy link

rmongia commented Aug 11, 2014

that's interesting. i have tested the scenario with my setup and it seems to work. my setup is a simple recommended configuration with a few custom rules. i am not using OWASP rule set here.

My guess is there is some rule which is doing this. You can investigate further by disabling all rules and running the same scenario again.

@zimmerle
Copy link
Contributor

Fixed by: #749.

daniilyar pushed a commit to daniilyar/ModSecurity that referenced this issue Feb 5, 2016
chewi pushed a commit to yakara-ltd/ModSecurity that referenced this issue May 2, 2016
chewi pushed a commit to yakara-ltd/ModSecurity that referenced this issue May 2, 2016
@davidgenn
Copy link

Hi @zimmerle Has this been included in a release?

I've just compiled the latest version of Nginx (1.11.6) with Modsecurity (2.9.1). Nginx is acting as a reverse proxy for a Jetty server. I'm using the default OWASP rules (3.0.0).

The Java app is adding headers to the response which are being stripped out by Modsecurity. It was fine before Modsecurity was added.

Thanks in advance!

@zimmerle
Copy link
Contributor

Hi @davidgenn,

Please use the `nginx_refactoring' branch. Or the ModSecurity-nginx connector:
https://github.com/SpiderLabs/ModSecurity-nginx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants