Nginx cache seems to swallow Set-Cookie

I run nginx 0.7.67 as a frontend proxy and cache for my Java application
running on jetty 7 using proxy_pass and proxy_cache.

nginx runs on port 80, the java app on 8080.

The very first thing the java application does when I call it in the
browser ( http://localhost ) is create a new http session and send a 302
redirect to the login page. The response contains a new “Set-Cookie:
JSESSIONID=65omgcih3oif15g2yc1szsos;Path=/” with some new random session
ID. The 302 also contains a “Cache: no-cache” so the 302 temporary
redirect never gets cached which is what we want.

Now what I experience is that nginx returns the java app server response
with all but the “Set-Cookie”. It’s definitely there and nginx
definitely removes it.

This is a real pain and will break my app (and possible others).

So is there such a thing like a “cookie-stripper-during-http-status-302”
?

this is my config:


user nobody nogroup;
worker_processes 4;

error_log logs/error.log info;
pid logs/nginx.pid;

events {
worker_connections 256;
}

http {
include mime.types;
default_type application/octet-stream;

sendfile on;

gzip on;
gzip_comp_level 2;
gzip_proxied any;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_types text/plain text/css application/x-javascript text/xml
application/xml application/xml+rss text/javascript image/gif image/jpeg
image/png;

upstream jetty {
ip_hash;
server localhost:8080;
# more will follow
}

proxy_temp_path /usr/local/nginx-0.7.67/tmp;
proxy_cache_path /usr/local/nginx-0.7.67/cache/default levels=1:2
keys_zone=default:8m max_size=1000m inactive=600m;
proxy_cache_valid 200 302 60s;
proxy_cache_key “$scheme://$host$request_uri”;

server
{
listen 80;
listen [::]:80 default ipv6only=on;

location / {
  proxy_cache default;
  proxy_pass http://jetty/;
  proxy_redirect     default;
  proxy_set_header   Host      $host;
  proxy_set_header   X-Forwarded-Host  $host;
  proxy_set_header   X-Real-IP    $remote_addr;
  proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
}

}
}

Posted at Nginx Forum:

Hello!

On Thu, Sep 02, 2010 at 09:02:15AM -0400, pertl wrote:

redirect never gets cached which is what we want.

Now what I experience is that nginx returns the java app server response
with all but the “Set-Cookie”. It’s definitely there and nginx
definitely removes it.

This is a real pain and will break my app (and possible others).

So is there such a thing like a “cookie-stripper-during-http-status-302”
?

In 0.7.67 nginx strips Set-Cookie headers by default on all
responses served with proxy_cache switched on. You may change
this with proxy_pass_header directive (note that this will cause
cached responses to return Set-Cookie header as well, you have
to make sure your backend doesn’t return personal cookies on
cacheable responses).

Note that in 0.8.44 behaviour was changed to something considered
more natural. As of 0.8.44 nginx no longer caches responses with
Set-Cookie header and doesn’t strip this header with cache turned
on (unless you instruct it to do so with proxy_hide_header and
proxy_ignore_headers).

Maxim D.

Hello!

On Thu, Sep 02, 2010 at 10:27:01AM -0400, pertl wrote:

Thank you Maxim,

you saved my day :slight_smile:

Caching performance is quite an issue for the application we develop
here, so:

Is it already considered safe to use 0.8.49 in production environments
or would you strongly advise against that?

It’s safe.

Maxim D.

Thank you Maxim,

you saved my day :slight_smile:

Caching performance is quite an issue for the application we develop
here, so:

Is it already considered safe to use 0.8.49 in production environments
or would you strongly advise against that?

Posted at Nginx Forum:

On Thu, Sep 02, 2010 at 10:27:01AM -0400, pertl wrote:

Thank you Maxim,

you saved my day :slight_smile:

Caching performance is quite an issue for the application we develop
here, so:

Is it already considered safe to use 0.8.49 in production environments
or would you strongly advise against that?

Yes, 0.8.x is used in production environments. However, it’s better to
use
just released 0.8.50, since it fixes a serious bug in 0.8.48/49.


Igor S.
http://sysoev.ru/en/

Wow, you guys are really helpful!!!

Thanks a lot :slight_smile:

Posted at Nginx Forum:

Maxim D. Wrote:

In 0.7.67 nginx strips Set-Cookie headers by
default on all
responses served with proxy_cache switched on.
ARRGHHH!!! This is not documented in the changelog and I was going
crazy on why my apps which had been working perfectly fine suddenly
stopped working on upgrading to 0.7.67.
You may change
this with proxy_pass_header directive (note that
this will cause
cached responses to return Set-Cookie header as
well,
ARRGHHH!!!
you have
to make sure your backend doesn’t return personal
cookies on
cacheable responses).

Note that in 0.8.44 behaviour was changed to
something considered
more natural. As of 0.8.44 nginx no longer caches
responses with
Set-Cookie header and doesn’t strip this header
with cache turned
on (unless you instruct it to do so with
proxy_hide_header and
proxy_ignore_headers).
A far more rational approach … hope to see this in the 0.7 branch
quickly (0.8.x is a not doable for me)as this undocumented change has
essentially made 0.7.67 unusable.
I need to roll back and give up the proxy no cache use I upgraded for.

Posted at Nginx Forum:

Hello!

On Mon, Sep 06, 2010 at 10:46:16AM -0400, Dayo wrote:

Maxim D. Wrote:

In 0.7.67 nginx strips Set-Cookie headers by
default on all
responses served with proxy_cache switched on.
ARRGHHH!!! This is not documented in the changelog and I was going
crazy on why my apps which had been working perfectly fine suddenly
stopped working on upgrading to 0.7.67.

0.7.52:

*) Bugfix: now the "Set-Cookie" and "P3P" header lines are hidden in
   cacheable responses.

Basically this is how it used to work since introduction of cache
in 0.7., at least in all 0.7. stable releases (cache was
introduced in 0.7.48, 0.7.* branch was marked stable at 0.7.59).

Maxim D.

Hi!

Maxim D. Wrote:

Basically this is how it used to work since
introduction of cache
in 0.7., at least in all 0.7. stable releases
(cache was
introduced in 0.7.48, 0.7.* branch was marked
stable at 0.7.59).
I had changed from proxying php to apache and I didn’t add
“fastcgi_pass_header” to my new config which was what was causing the
issue.

Thanks for clarifying!

Posted at Nginx Forum:

I realize that this is an old thread but it relates to my question. I
use proxy_cache with a somewhat special approach.
User can log in to our site that has been designed to be completely
reverse proxy cacheable, even when a user is logged in. We use a
separate json call to retrieve session information for the user.

So some pages like /product/* are cacheable but they may still be
retrieved by a logged in user. I want to make sure that the set cookie
doesn’t get accidently get cached and allow another user to access my
session. Just this kind of thing seemed to happen the other day when an
anonymous user was suddenly logged in under my account, so now I’m not
sure how to see it. I am hoping that this was an issue related to a
stale proxy_cache that accumulated “illegal” content over the course of
development and changes in configuration.

The desired functionality is;
Anonymous useer

  • request cacheablepage1.html
  • retrieve from cache if available => cachefile01
  • put in cache
    Logged in user
  • request cacheablepage1.html
  • retrieve from cache => cachefile01
  • request cacheablepage2.html
  • retrieve from cache if availabel
  • put in cache but strip any set-cookie associated with the session
    => cachefile02
  • get cachefile02
    Anonymous user
  • request cacheablepage2.html
  • retrieve from cache if available => cachefile02
    Any result from a POST
    * never put in proxy cache

My current config for this is

server {
  listen                80 default_server;
  server_name           _;
  server_name_in_redirect    off;
  charset           utf-8;
  root                  /var/lib/APP;
  add_header      Cache-Control public;

  set $proxy_bypass     off;

  [..]

  location ~ (cart|account|editor|admin)$ {
    set $proxy_bypass    on;
    try_files        $uri @proxy;
  }
  location / {
    keepalive_timeout     30;
    rewrite         ^([^.]*[^/])$ $1/ permanent;
    try_files         $uri @proxy;
  }
  location @proxy {
    proxy_cache        STATIC;
    proxy_pass        http://localhost:9000;
    proxy_cache_valid     200 15m;
    proxy_cache_valid     404  5m;
    proxy_cache_use_stale    error timeout invalid_header updating
                               http_500 http_502 http_503 http_504;
    proxy_cache_key     $host$request_uri;
    proxy_ignore_headers  Set-Cookie;
    proxy_cache_bypass     $proxy_bypass;

    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        Host $http_host;
    #proxy_max_temp_file_size 0;
    proxy_buffering     on;
    #proxy_store      off;

    proxy_connect_timeout   30;
    proxy_send_timeout      30;
    proxy_read_timeout      30;

    # All POST requests go directly
    if ($request_method = POST) {
      proxy_pass http://localhost:9000;
      break;
    }
  }

Are my assumptions correct? What directes are important to pay attention
to in order to avoid accidental session access for the wrong user?

Kind regards,

Marc

Posted at Nginx Forum:

Hello!

On Thu, Jan 13, 2011 at 04:52:02PM -0500, mschipperheyn wrote:

anonymous user was suddenly logged in under my account, so now I’m not

  • request cacheablepage1.html
  • never put in proxy cache
rewrite         ^([^.]*[^/])$ $1/ permanent;
proxy_ignore_headers  Set-Cookie;
proxy_send_timeout      30;

Are my assumptions correct? What directes are important to pay attention
to in order to avoid accidental session access for the wrong user?

  1. proxy_cache_bypass will bypass cache with both “off” and “on”
    values, as both are evaluated to true; and more importantly -
    proxy_cache_bypass doesn’t work correctly as of now if not used
    with identical proxy_no_cache due to bug, so just forget about it

  2. to strip Set-Cookie from replies you have to use
    proxy_hide_header Set-Cookie; it’s not clear why you ever return
    cookies with cacheable pages though

  3. POST requests aren’t cached by default, no need for an if; and
    your if relies on this anyway as it doesn’t contain proxy_cache
    off;

Maxim D.