5

The following is a result of a bug within WebKit's Dev Tools used by Google Chrome and Apple's Safari. I have made a bug report with CrBug, who then identified the regression within WebKit Changeset 116952. I would like to thank @Grumpy and @Matthieu Cormier for their help is tracking this one down. I can't wait for the next build of Chrome Canary :).


I have nginx setup on my server along with PHP-FPM, and during making a new website and trying to make sure that it is as quick as possible I went through Google Chrome's Audit tools. Among some of the errors it gave me this.

Leverage proxy caching (10)
The following publicly cacheable resources contain a Set-Cookie
header. This security vulnerability can cause cookies to be shared
by multiple users.

So what I would like to know is, what do I have to add to the following statement in order for it not to set a Set-Cookie header for this domain. I would then take that information and apply it to css, img, ect subdomains so that it can be properly cached by the browser.

server {
    gzip on;
    gzip_static on;

    listen          80;
    server_name     img.domain.tld;
    root            /www/domain/tld;
    index           index.php index.htm index.html;

    location ~* \.(gif|png|jpg|jpeg|svg)$ {
        expires 30d;
    }

    include php_fpm;
}

Follow up for request for more information by Grumpy.

Here is the configuration file that I am for the PHP FPM include, used in the img sub domain.

The PHP-FPM include

location ~ \.php$ {
    fastcgi_pass    unix:/tmp/php.socket;
    fastcgi_param   SCRIPT_FILENAME
                    $document_root$fastcgi_script_name;
    include         fastcgi_params;
}

As you can see, it should only activate when the location ends with a php file extension.

Funny thing is, I also have a css file that is being reported as having a set-cookie header, and that's being served by the css subdomain that does not have a php-fpm included in it ... here is that part of the configuration file.

server {
    gzip_static on;

    listen          80;
    server_name     css.domain.tld;
    root            /www/domain/css;
    index           index.htm index.html;

    location ~* \.(css)$ {
        expires 7d;
    }
}

The files are ...

Leverage proxy caching (5)
    The following publicly cacheable resources contain a Set-Cookie 
    header. This security vulnerability can cause cookies to be shared
    by multiple users.
  • style.css (served by css.domain.tld)
  • 2009EMSWeekLogoSmall.jpg (served by domain.tld)
  • EMS%20FOUR.jpg (served by domain.tld)
  • get_adobe_reader.png (served by img.domain.tld)
  • dhs-ntas-badge-small.jpg (served by dhs.gov)

the domain.tld server configuration looks like this.

server {
    gzip on;
    gzip_static on;

    listen          80;
    server_name     .domain.tld;
    root            /www/domain/www;
    index           index.php index.htm index.html;

    location ~* \.(htm|html|ico|icns|hqx|gif|png|svg|jpg|jpeg|svg)$ {
        expires 1d;
    }

    include php_fpm;
}
Martin Thoma
  • 247
  • 4
  • 13
Mark Tomlin
  • 620
  • 3
  • 10
  • 23
  • This bug has now been reported, you can find the bug report here. [Audit Tool's False Positive on Set-Cookie header, from a cookie-less domain sub domain.](http://code.google.com/p/chromium/issues/detail?can=2&q=cookies%20chrome%20audit%20tools&colspec=ID%20Pri%20Mstone%20ReleaseBlock%20OS%20Area%20Feature%20Status%20Owner%20Summary&id=169771&thanks=169771&ts=1358153854). Thank you Grumpy & Matthieu Cormier for the assist in finding this bug. Please note this issue persists in Google Chrome v24.0.1312.52 m that was released Thursday Jaunary 10th, 2013. – Mark Tomlin Jan 14 '13 at 09:03

3 Answers3

12

Although in your case it seems like you might be hitting some bug in the tool that reports that your graphic files contain a Set-Cookie directive (it's extremely unlikely that you'd be having "Set-Cookie" stuff in static files served directly by nginx with the setup you describe), I have actually encountered a situation where a Java webapp was setting some cookies I didn't want to have set.

This can be addressed through nginx with the following directives placed within the server context (change proxy_ to fastcgi_ as required):

    proxy_hide_header       Set-Cookie;
    proxy_ignore_headers    Set-Cookie;
    # important! Remember the special inheritance rules for proxy_set_header:
    # http://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_set_header
    proxy_set_header        Cookie "";

All three directives above are very important: proxy_hide_header ensures the header will not be passed back to the client, proxy_ignore_headers ensures that the header will not automatically disable caching within nginx and, finally, proxy_set_header ensures that a client cannot pass any prior cookies to the webapp and spoil your cache. Note my comment regarding proxy_set_header inheritance — you cannot nest this directive (have to define all or none at a given level).

Obviously, you will also have to ensure that all your webapps still work after nuking away the cookies in such a way as above. But I know firsthand that the above does work great at getting rid of the HTTP-passed cookies!

cnst
  • 12,948
  • 7
  • 51
  • 75
  • It would be awesome if I could apply the hide header or ignore header to specific files, using the location directive within nginx configuration files. Thank you for the post, I'm sure someone will find this very useful. – Mark Tomlin Jan 14 '13 at 08:41
  • You can -- just make sure to apply it to every context that has any `proxy_` or `fastcgi_` etc directives and needs its cookies ignored. (There's obviously no need to apply it to any locations that only serve static files.) Note that it's easier to make a mistake in the application to only specific locations (e.g. by trying to apply to various redirect locations instead of the actual locations that interface with the backend). Applying this to redirect/rewrite-only locations might not produce any results. – cnst Jan 14 '13 at 17:56
2

Identifying a resource to be cached is a non-default behavior. So, whatever is causing this notification by Chrome is an object you specified to be cached.

The directive to cache (public in this case) can be set in 2 ways.

  1. Your nginx tells it to cache.
  2. PHP tells it to cache, which is then forwarded by nginx.

Per your above nginx configuration, and ignoring the entire include php_fpm;, there's nothing which would suggest #1 unless your images (gif, jpg, png) are somehow being executed.

It's also possible that PHP has such cache directive. In such case, it's something you really should be fixing from the core rather than trying to do a patch up job.

But with these two cases, you can also enter an odd scenario. If your image is not found, it will attempt to find a 404 page. And if 404 is an executable (php) either directly or indirectly, it can then carry a set cookie command. This would be a poor behavior if 404 directive is also tells it to be cached. So, be sure to check that as well. The same also obviously applies to any other error codes.

This is about all I can guess given the current information. You may want to follow up with additional information as to which exact item is causing the Chrome to give such message, if there are any errors found as well as full configuration of nginx and/or php-fpm.


I tried looking at the full HTTP headers to see if there's any indication of cookies or any custom information being passed around.

Sample response header from OP's site causing warnings.

telnet img.nassauems.net 80
Trying 205.186.162.66...
Connected to img.nassauems.net.
Escape character is '^]'.
GET http://img.nassauems.net/buttons/get_adobe_reader.png HTTP/1.1
Host: img.nassauems.net

HTTP/1.1 200 OK
Server: nginx/1.2.4
Date: Sat, 12 Jan 2013 20:24:19 GMT
Content-Type: image/png
Content-Length: 2597
Last-Modified: Fri, 28 Dec 2012 08:30:57 GMT
Connection: keep-alive
Expires: Mon, 11 Feb 2013 20:24:19 GMT
Cache-Control: max-age=2592000
Accept-Ranges: bytes

Sample response header from my site that doesn't cause warnings.

telnet www.mysite.com 80
Trying 123.123.123.123...
Connected to www.mysite.com.
Escape character is '^]'.
GET http://www.mysite.com/test.png HTTP/1.1
Host: www.mysite.com

HTTP/1.1 200 OK
Server: nginx/1.0.12
Date: Sat, 12 Jan 2013 20:21:43 GMT
Content-Type: image/png
Content-Length: 207
Last-Modified: Sat, 27 Aug 2011 04:42:30 GMT
Connection: keep-alive
Expires: Sun, 13 Jan 2013 20:21:43 GMT
Cache-Control: max-age=86400
Accept-Ranges: bytes

Can you spot the difference? I can't!

I would label this as a bug with Chrome Audit.

Grumpy
  • 2,939
  • 17
  • 23
  • First, great avatar, second, I've updated the original question with the details you have asked for. – Mark Tomlin Jan 12 '13 at 09:31
  • @MarkTomlin If you look from Chrome's dev tools, you should be able to see exactly **what** cookie was set with these static files. But quite frankly, sort of stumped atm. – Grumpy Jan 12 '13 at 18:19
  • The site if you want to take a look yourself is [nassauems.net](http://nassauems.net). None of the files listed have anything that says anything about cookies. So I'm also stumped. – Mark Tomlin Jan 12 '13 at 19:41
  • @MarkTomlin I took a look. Tried various tests. Tried audits from other tools. Nothing. I append the raw outputs to above and frankly don't see any difference why the 2nd is treated differently from the first. I think it's a bug with chrome. – Grumpy Jan 12 '13 at 20:32
1

I recently noticed this and and am experiencing the same thing.

I'm confident that this is a bug in Chrome.

  1. I looked at the response headers in the Safari Web Inspector and it does not show a Set-Cookie either.
  2. I telnetted directly to my web server and executed a GET request and examined the raw headers, there is no Set-Cookie line.

Chrome may be detecting something and outputting an invalid description, or it might just be a plain bug.

Using Chrome 24.0.1312.52 on OS X

Using Safari Version 6.0.2 (8536.26.17) on OS X