通过删除 Set-Cookie 标头来利用 nginx 的代理缓存

Mar*_*lin 5 nginx cookies

以下是 Google Chrome 和 Apple 的 Safari 使用的 WebKit 开发工具中的错误的结果。我用 CrBug做了一个错误报告,然后他确定了WebKit Changeset 116952 中的回归。我要感谢 @Grumpy 和 @Matthieu Cormier 的帮助,他们正在追踪这个问题。我等不及 Chrome Canary 的下一个版本了 :)。


我在我的服务器上安装了 nginx 和 PHP-FPM,在创建一个新网站并尝试确保它尽可能快的过程中,我使用了谷歌浏览器的审计工具。在它给我的一些错误中。

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.
Run Code Online (Sandbox Code Playgroud)

所以我想知道的是,为了不为该域设置 Set-Cookie 标头,我必须在以下语句中添加什么。然后我将获取该信息并将其应用于 css、img 等子域,以便浏览器可以正确缓存它。

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;
}
Run Code Online (Sandbox Code Playgroud)

跟进Grumpy对更多信息的请求。

这是我为PHP FPM包含的配置文件,用于img子域。

PHP-FPM 包括

location ~ \.php$ {
    fastcgi_pass    unix:/tmp/php.socket;
    fastcgi_param   SCRIPT_FILENAME
                    $document_root$fastcgi_script_name;
    include         fastcgi_params;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,它应该仅在位置以 php 文件扩展名结尾时激活。

有趣的是,我还有一个 css 文件,它被报告为有一个 set-cookie 标头,并且它由没有包含 php-fpm 的 css 子域提供服务......这是其中的一部分配置文件。

server {
    gzip_static on;

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

    location ~* \.(css)$ {
        expires 7d;
    }
}
Run Code Online (Sandbox Code Playgroud)

这些文件是...

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.
Run Code Online (Sandbox Code Playgroud)
  • style.css(由css .domain.tld 提供)
  • 2009EMSWeekLogoSmall.jpg(由domain.tld提供)
  • EMS%20FOUR.jpg(由 domain.tld 提供)
  • get_adobe_reader.png(由img .domain.tld 提供)
  • dhs-ntas-badge-small.jpg(由 dhs.gov 提供)

domain.tld 服务器配置如下所示。

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;
}
Run Code Online (Sandbox Code Playgroud)

cns*_*nst 12

尽管在您的情况下,您似乎在报告图形文件包含Set-Cookie指令的工具中遇到了一些错误(您极不可能在由 nginx 直接提供的静态文件中使用“Set-Cookie”内容设置),我实际上遇到过这样一种情况,即 Java Web 应用程序设置了一些我不想设置的 cookie。

这可以通过与nginx的放置在内的以下指令来解决server上下文(改变proxy_fastcgi_根据需要):

    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 "";
Run Code Online (Sandbox Code Playgroud)

以上三个指令都非常重要:proxy_hide_header确保标头不会被传递回客户端,proxy_ignore_headers确保标头不会自动禁用 nginx 中的缓存,最后,proxy_set_header确保客户端不会将任何先前的 cookie 传递给 webapp 并破坏您的缓存。请注意我关于proxy_set_header继承的评论——您不能嵌套此指令(必须在给定级别定义 all 或 none)。

显然,您还必须确保您的所有网络应用程序在以上述方式清除 cookie 后仍能正常工作。但我直接知道上面的方法在摆脱 HTTP 传递的 cookie 方面确实很有效!


Gru*_*mpy 2

识别要缓存的资源是非默认行为。因此,Chrome 发出此通知的原因是您指定要缓存的对象。

缓存指令(在本例中为公共)可以通过两种方式设置。

  1. 你的 nginx 告诉它缓存。
  2. PHP告诉它缓存,然后由nginx转发。

根据您上面的 nginx 配置,并忽略整个include php_fpm;,没有什么建议#1,除非您的图像(gif、jpg、png)以某种方式被执行。

PHP 也可能有这样的缓存指令。在这种情况下,您确实应该从核心进行修复,而不是尝试进行修补工作。

但对于这两种情况,你也可能会进入一个奇怪的场景。如果找不到您的图像,它将尝试查找 404 页面。如果 404 是直接或间接的可执行文件(php),则它可以携带 set cookie 命令。如果 404 指令也告诉它被缓存,这将是一个糟糕的行为。所以,一定要检查一下。这显然也适用于任何其他错误代码。

鉴于目前的信息,这就是我能猜测的全部内容。如果发现任何错误,以及 nginx 和/或 php-fpm 的完整配置,您可能需要跟进其他信息,了解到底是哪个项目导致 Chrome 给出此类消息。


我尝试查看完整的 HTTP 标头,看看是否有任何 cookie 或任何自定义信息正在传递的迹象。

来自 OP 站点的示例响应标头导致警告。

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
Run Code Online (Sandbox Code Playgroud)

我的网站的示例响应标头不会导致警告。

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
Run Code Online (Sandbox Code Playgroud)

您看得出来差别吗?我不能!

我会将此标记为 Chrome Audit 的错误。