安全相关的HTTP响应头

本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。

这一部分文档讨论的是安全相关的 HTTP 响应头的一般主题。有关基于 servlet 和 WebFlux 的应用程序中安全HTTP响应头的具体信息,请参见相关章节。

你可以通过多种方式使用 HTTP响应头 来提高Web应用程序的安全性。本节将专门介绍 Spring Security 提供明确支持的各种HTTP响应头。如果有必要,你也可以配置 Spring Security 来提供 自定义 header 信息。

默认的 Security Header

关于如何为基于 servlet 和 webflux 的应用程序定制默认值,请参阅相关章节。

Spring Security提供了一套默认的安全相关的HTTP响应头,以提供安全的默认值。

Spring Security 的默认做法是包括以下 Header。

Default Security HTTP Response Headers
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
X-XSS-Protection: 0

仅在HTTPS请求中添加 Strict-Transport-Security。

如果默认值不能满足你的需要,你可以很容易地从这些默认值中删除、修改或添加 Header。关于这些 Header 的其他细节,请参见相应的章节。

缓存控制(Cache Control)

关于如何为基于 servlet 和 webflux 的应用程序定制默认值,请参阅相关章节。

Spring Security的默认设置是禁用缓存以保护用户的内容。

如果用户通过认证查看敏感信息,然后注销,我们不希望恶意的用户能够点击返回按钮查看敏感信息。默认发送的缓存控制 Header 如下。

Default Cache Control HTTP Response Headers
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0

为了安全起见,Spring Security 默认添加了这些 Header。然而,如果你的应用程序提供了自己的缓存控制 Header,Spring Security 就会退居二线。这允许应用程序确保静态资源(如CSS和JavaScript)可以被缓存。

Content Type Options

请参考相关章节,看看如何为基于 servlet 和 webflux 的应用程序定制默认值。

历史上,包括 Internet Explorer 在内的浏览器会通过 内容嗅探 来猜测请求的内容类型。这使得浏览器可以通过猜测没有指定内容类型的资源的内容类型来改善用户体验。例如,如果浏览器遇到一个没有指定内容类型的JavaScript文件,它就能猜出内容类型,然后运行它。

在允许上传内容时,人们应该做许多额外的事情(比如只在指定的域中显示文档,确保 Content-Type 头被设置,对文档进行“消毒”(安全处理),以及其他)。然而,这些措施已经超出了 Spring Security 所提供的范围。同样重要的是要指出,在禁用内容嗅探时,你必须指定内容类型,以便事情能够正常进行。

内容嗅探的问题在于,这使得恶意用户可以使用多语言(即一个文件可以作为多种内容类型有效)来进行XSS攻击。例如,一些网站可能允许用户提交一个有效的postscript文件到网站上并查看它。恶意用户可能会创建 一个也是有效的JavaScript文件的postscript文档,并利用它进行XSS攻击。

默认情况下,Spring Security 通过向 HTTP 响应添加以下头来禁用内容嗅探。

nosniff HTTP Response Header
X-Content-Type-Options: nosniff

HTTP严格传输安全 (HSTS)

请参考相关章节,看看如何为基于 servlet 和 webflux 的应用程序定制默认值。

当你输入银行的网站时,你是输入 mybank.example.com 还是输入 https://mybank.example.com ?如果你省略了https协议,你就有可能受到中间人攻击。即使网站执行重定向到 https://mybank.example.com,一个恶意的用户可以拦截最初的HTTP请求并操纵响应(例如,重定向到 https://mibank.example.com,并窃取他们的证书)。

许多用户省略了https协议,这就是 HTTP严格传输安全(HSTS) 产生的原因。一旦 mybank.example.com 被添加为 HSTS host,浏览器可以提前知道任何对 mybank.example.com 的请求都应该被解释为 https://mybank.example.com。这大大减少了中间人攻击发生的可能性。

根据 RFC6797,HSTS 头只被注入HTTPS响应中。浏览器要想确认该Header,首先必须信任签署用于建立连接的SSL证书的CA(而不仅仅是SSL证书)。

一个网站被标记为 HSTS HOST 的方法是将该 HOST 预装到浏览器中。另一种方法是在响应中添加 Strict-Transport-Security header。例如,Spring Security 的默认行为是添加以下 header,指示浏览器将该域作为HSTS HOST处理一年(在非闰年有31536000秒)。

Strict Transport Security HTTP Response Header
Strict-Transport-Security: max-age=31536000 ; includeSubDomains ; preload

可选的 includeSubDomains 指令指示浏览器,子域(如 secure.mybank.example.com)也应被视为HSTS域。

可选的 preload 指令指示浏览器,该域应作为 HSTS 域在浏览器中预加载。关于HSTS预加载的更多细节,请参见 hstspreload.org 。

HTTP 公钥锁定 (HPKP)

为了保持被动,Spring Security 仍然 为 Servlet 环境中的 HPKP 提供支持。然而,由于前面列出的原因,Spring Security 团队不再推荐使用HPKP。

HTTP公钥锁定(HTTP Public Key Pinning) (HPKP)向网络客户指定在某个网络服务器上使用哪个公钥,以防止使用伪造证书的中间人(MITM)攻击。如果使用得当,HPKP可以增加额外的保护层,防止证书被破坏。然而,由于HPKP的复杂性,许多专家不再建议使用它, Chrome浏览器甚至取消了对它的支持。

关于为什么不再推荐HPKP的其他细节,请阅读 Is HTTP Public Key Pinning Dead? 和 I’m giving up on HPKP.

X-Frame-Options

参见相关章节,了解如何为基于 servlet 和 webflux 的应用程序定制默认值。

让你的网站被添加到一个 frame 中可能是一个安全问题。例如,通过使用巧妙的CSS样式设计,用户可能会被骗去点击他们不打算点击的东西。例如,一个登录了银行的用户可能会点击一个授予其他用户访问权限的按钮。这类攻击被称为 点击劫持(Clickjacking)。

另一种处理点击劫持的现代方法是使用 Content Security Policy (CSP)。

有许多方法可以减轻点击劫持攻击。例如,为了保护传统的浏览器免受点击劫持攻击,你可以使用 frame breaking code。虽然不完美,但对于传统的浏览器来说,frame breaking code 是你能做的最好的。

解决点击劫持的一个更现代的方法是使用 X-Frame-Options 头。默认情况下,Spring Security 通过使用以下 Header 来禁止在 iframe 内渲染页面。

X-Frame-Options: DENY

X-XSS-Protection

参见相关章节,了解如何为基于 servlet 和 webflux 的应用程序定制默认值。

一些浏览器内置支持过滤掉 反射的XSS攻击。在主要的浏览器中,该过滤器已被废弃,目前 OWASP的建议 是明确地将该Header设置为0。

默认情况下,Spring Security通过使用以下 header 来阻止该内容。

X-XSS-Protection: 0

Content Security Policy (CSP)

参见相关章节,了解如何配置基于 servlet 和 webflux 的应用程序。

内容安全策略(Content Security Policy) (CSP)是一种机制,web应用可以用来缓解内容注入漏洞,如跨站脚本(XSS)。CSP是一种声明性的策略,为web应用程序作者提供了一种设施,以声明并最终告知客户端(user-agent)web应用程序期望加载资源的来源。

内容安全策略的目的不是为了解决所有的内容注入漏洞。相反,你可以使用CSP来帮助减少内容注入攻击造成的危害。作为第一道防线,web应用程序作者应该验证他们的输入并对他们的输出进行编码。

一个web应用程序可以通过在响应中包括以下HTTP头信息之一来使用CSP。

  • Content-Security-Policy

  • Content-Security-Policy-Report-Only

这些Header中的每一个都被用来作为向客户提供安全策略的机制。一个安全策略包含一组安全策略指令,每个指令负责声明对特定资源表示的限制。

例如,一个web应用程序可以通过在响应中包括以下 Header 来声明它期望从特定的、受信任的来源加载脚本。

Content Security Policy Example
Content-Security-Policy: script-src https://trustedscripts.example.com

试图从 script-src 指令中声明的以外的其他来源加载脚本会被用户代理(user-agent)阻止。此外,如果安全策略中声明了 report-uri 指令,用户代理将向声明的URL报告违规行为。

例如,如果一个Web应用程序违反了声明的安全策略,下面的响应头指示用户代理将违规报告发送到策略的 report-uri 指令中指定的URL。

Content Security Policy with report-uri
Content-Security-Policy: script-src https://trustedscripts.example.com; report-uri /csp-report-endpoint/

违规报告 是标准的JSON结构,可以由web应用程序自身的API或由公开托管的CSP违规报告服务(如 report-uri.io/ )捕获。

Content-Security-Policy-Report-Only Header 为 web 应用程序作者和管理员提供了监控安全策略的能力,而不是强制执行这些策略。这个 Header 通常在为网站试验或开发安全策略时使用。当一个策略被认为是有效的,它可以通过使用 Content-Security-Policy Header 来代替执行。

考虑到下面的响应头,该策略声明脚本可以从两个可能的来源之一加载。

Content Security Policy Report Only
Content-Security-Policy-Report-Only: script-src 'self' https://trustedscripts.example.com; report-uri /csp-report-endpoint/

如果网站违反了这一政策,试图从 evil.example.com 加载一个脚本,用户代理会向 report-uri 指令指定的声明的URL发送一份违规报告,但仍让违规资源加载。

将内容安全策略应用于 web 应用程序往往是一项非同小可的工作。以下资源可以为你的网站制定有效的安全策略提供进一步的帮助。

Referrer Policy

参见相关章节,了解如何配置基于 servlet 和 webflux 的应用程序。

Referrer Policy 是一种机制,Web应用程序可以用来管理 referrer 字段,它包含用户最后浏览的页面。

Spring Security的方法是使用 Referrer Policy Header,它提供了不同的 策略。

Referrer Policy 示例
Referrer-Policy: same-origin

Referrer-Policy 响应头指示浏览器让目的地知道用户之前所在的来源。

Feature Policy

参见相关章节,了解如何配置基于 servlet 和 webflux 的应用程序。

Feature Policy 是一种机制,让weh开发者有选择地启用、禁用和修改浏览器中某些API和网络功能的行为。

Feature Policy 示例
Feature-Policy: geolocation 'self'

通过功能策略,开发者可以选择加入一套 "策略",让浏览器对整个网站使用的特定功能进行强制执行。这些策略限制了网站可以访问的API,或修改浏览器对某些功能的默认行为。

Permissions Policy

参见相关章节,了解如何配置基于 servlet 和 webflux 的应用程序。

Permissions Policy 是一种机制,让网络开发者有选择地启用、禁用和修改浏览器中某些API和网络功能的行为。

Permissions Policy Example
Permissions-Policy: geolocation=(self)

通过权限策略,开发者可以选择加入一套 "策略",让浏览器对整个网站使用的特定功能进行强制执行。这些策略限制了网站可以访问的API,或修改浏览器对某些功能的默认行为。

清除网站数据

参见相关章节,了解如何配置基于 servlet 和 webflux 的应用程序。

清除网站数据(Clear Site Data) 是一种机制,当HTTP响应包含这个 Header 时,任何浏览器方面的数据(cookie、local storage 等)都可以被删除。

Clear-Site-Data: "cache", "cookies", "storage", "executionContexts"

这是一个很好的清理动作,可以在注销时执行。

自定义Header

参见相关章节,了解如何配置基于 servlet 的应用程序。

Spring Security 有一些机制,可以方便地在你的应用程序中添加更常见的安全 Header。然而,它也提供了钩子来实现添加自定义 Header 信息。