# 安全 HTTP 响应标头

|   |文档的这一部分讨论了安全 HTTP 响应头的一般主题。<br/>关于基于应用程序的安全 HTTP 响应头[servlet](../../servlet/exploits/headers.html#servlet-headers)和[WebFlux](../../reactive/exploits/headers.html#webflux-headers)的特定信息，请参阅相关部分。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

有许多[HTTP 响应标头](https://owasp.org/www-project-secure-headers/#div-headers)可以用来增加 Web 应用程序的安全性。本节专门讨论 Spring Security 提供明确支持的各种 HTTP 响应头。如果需要， Spring 还可以将安全性配置为提供[自定义标头](#headers-custom)。

## 默认安全标头

|   |参考相关章节，了解如何为基于[servlet](../../servlet/exploits/headers.html#servlet-headers-default)和[webflux](../../reactive/exploits/headers.html#webflux-headers-default)的应用程序定制默认值。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

Spring 安全性提供了一组与安全性相关的默认 HTTP 响应头，以提供安全的默认值。

Spring 安全性的默认设置是包含以下标题：

例 1。默认安全 HTTP 响应标头

```
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: 1; mode=block
```

|   |严格传输安全性仅在 HTTPS 请求中添加|
|---|---------------------------------------------------------|

如果默认值不能满足你的需求，那么你可以轻松地从这些默认值中删除、修改或添加标题。有关每个标题的其他详细信息，请参阅相应的部分：

* [缓存控制](#headers-cache-control)

* [内容类型选项](#headers-content-type-options)

* [HTTP 严格的传输安全](#headers-hsts)

* [X-帧-选项](#headers-frame-options)

* [X-XSS-保护](#headers-xss-protection)

## 缓存控制

|   |参考相关章节，了解如何为基于[servlet](../../servlet/exploits/headers.html#servlet-headers-cache-control)和[webflux](../../reactive/exploits/headers.html#webflux-headers-cache-control)的应用程序定制默认值。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

Spring 安全性的默认方式是禁用缓存，以保护用户的内容。

如果用户通过身份验证查看敏感信息，然后注销，我们不希望恶意用户能够单击“后退”按钮查看敏感信息。默认情况下发送的缓存控制头是：

例 2。默认缓存控制 HTTP 响应标头

```
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
```

为了在默认情况下保持安全， Spring Security 在默认情况下添加了这些标题。但是，如果你的应用程序提供了自己的缓存控制头 Spring，安全性就会退缩。这允许应用程序确保 CSS 和 JavaScript 等静态资源可以被缓存。

## 内容类型选项

|   |参考相关章节，了解如何为基于[servlet](../../servlet/exploits/headers.html#servlet-headers-content-type-options)和[webflux](../../reactive/exploits/headers.html#webflux-headers-content-type-options)的应用程序定制默认值。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

历史上，包括 Internet Explorer 在内的浏览器都会尝试使用[内容嗅探](https://en.wikipedia.org/wiki/Content_sniffing)来猜测请求的内容类型。这允许浏览器通过猜测未指定内容类型的资源上的内容类型来改善用户体验。例如，如果浏览器遇到一个没有指定内容类型的 JavaScript 文件，它将能够猜测内容类型，然后运行它。

|   |在允许上传内容时，还应该做很多其他事情（例如，只在一个不同的域中显示文档，确保设置了 Content-Type 头，对文档进行了消毒等）。<br/>但是，这些措施超出了 Spring 安全性所提供的范围。<br/>还需要指出的是，在禁用内容嗅探时，必须指定内容类型，以便使事情正常工作。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

内容嗅探的问题在于，这使得恶意用户能够使用多义词（即作为多个内容类型有效的文件）来执行 XSS 攻击。例如，一些网站可能允许用户向网站提交有效的 PostScript 文档并查看它。恶意用户可能会创建[PostScript 文档，也是一个有效的 JavaScript 文件](http://webblaze.cs.berkeley.edu/papers/barth-caballero-song.pdf)并对其执行 XSS 攻击。

Spring 安全性通过在 HTTP 响应中添加以下头来在默认情况下禁用内容嗅探：

示例 3.Nosniff HTTP 响应头

```
X-Content-Type-Options: nosniff
```

## HTTP严格传输安全(HSTS)

|   |参考相关章节，了解如何为基于[servlet](../../servlet/exploits/headers.html#servlet-headers-hsts)和[webflux](../../reactive/exploits/headers.html#webflux-headers-hsts)的应用程序定制默认值。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

当你在你的银行的网站上输入时，你是输入 mybank.example.com 还是输入[https://mybank.example.com](https://mybank.example.com)？如果你省略了 HTTPS 协议，那么你可能会受到[中间派攻击](https://en.wikipedia.org/wiki/Man-in-the-middle_attack)的攻击。即使网站执行重定向到[https://mybank.example.com](https://mybank.example.com)，恶意用户也可能拦截初始的 HTTP 请求并操纵响应（例如，重定向到[https://mibank.example.com](https://mibank.example.com)并窃取其凭据）。

许多用户省略了 HTTPS 协议，这就是创建[HTTP 严格传输安全](https://tools.ietf.org/html/rfc6797)的原因。一旦 mybank.example.com 被添加为[HSTS host](https://tools.ietf.org/html/rfc6797#section-5.1)，浏览器就可以提前知道，对 mybank.example.com 的任何请求都应该被解释为[https://mybank.example.com](https://mybank.example.com)。这大大降低了中锋出现的可能性。

|   |根据[RFC6797](https://tools.ietf.org/html/rfc6797#section-7.2)，HSTS 报头只被注入到 HTTPS 响应中。<br/>为了使浏览器承认报头，浏览器必须首先信任签署了用于建立连接的 SSL 证书（而不仅仅是 SSL 证书）的 CA。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

将站点标记为 HSTS 主机的一种方法是将主机预装到浏览器中。另一种方法是将`Strict-Transport-Security`头添加到响应中。例如， Spring Security 的默认行为是添加以下标题，该标题指示浏览器在一年内将该域视为 HSTS 主机（一年中大约有 31536000 秒）：

例 4。严格的传输安全 HTTP 响应头

```
Strict-Transport-Security: max-age=31536000 ; includeSubDomains ; preload
```

可选的`includeSubDomains`指令指示浏览器将子域（例如 secure.mybank.example.com）也视为 HSTS 域。

可选的`preload`指令指示浏览器将域作为 HSTS 域预装到浏览器中。有关 HSTS 预加载的更多详细信息，请参见[https://hstspreload.org](https://hstspreload.org)。

## HTTP公钥锁定（HPKP）

|   |为了保持被动 Spring 安全仍然提供，但是由于上面列出的原因，HPKP 不再由安全团队推荐。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

[HTTP 公钥固定](https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning)向 Web 客户端指定在特定 Web 服务器上使用哪种公钥，以防止使用伪造证书的 MITM 攻击。如果正确使用，HPKP 可以添加额外的保护层，以防止受损的证书。然而，由于 HPKP 的复杂性，许多专家不再推荐使用它和[Chrome 甚至取消了支持](https://www.chromestatus.com/feature/5903385005916160)。

有关不再推荐 HPKP 的其他详细信息，请参见[HTTP 公钥钉死了吗？](https://blog.qualys.com/ssllabs/2016/09/06/is-http-public-key-pinning-dead)和[我要放弃 HPKP 了。](https://scotthelme.co.uk/im-giving-up-on-hpkp/)。

## X-帧-选项

|   |参考相关章节，了解如何为基于[servlet](../../servlet/exploits/headers.html#servlet-headers-frame-options)和[webflux](../../reactive/exploits/headers.html#webflux-headers-frame-options)的应用程序定制默认值。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

允许你的网站被添加到一个框架可能是一个安全问题。例如，使用聪明的 CSS 样式的用户可能会被诱使点击一些他们不打算点击的东西。例如，已登录其银行的用户可能会单击授予其他用户访问权限的按钮。这种攻击被称为[点击劫持](https://en.wikipedia.org/wiki/Clickjacking)。

|   |另一种处理点击劫持的现代方法是使用[内容安全策略](#headers-csp)。|
|---|-------------------------------------------------------------------------------------------------------------|

有很多方法可以减轻点击劫持攻击。例如，要保护遗留浏览器免受点击劫持攻击，你可以使用[帧断代码](https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet#Best-for-now_Legacy_Browser_Frame_Breaking_Script)。虽然不是完美的，但断帧代码是你可以为传统浏览器做的最好的事情。

一个更现代的解决点击劫持的方法是使用[X-帧-选项](https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options)头。 Spring 默认情况下，安全性禁用使用以下标题在 IFRAME 中呈现页面：

```
X-Frame-Options: DENY
```

## X-XSS-保护

|   |参考相关章节，了解如何为基于[servlet](../../servlet/exploits/headers.html#servlet-headers-xss-protection)和[webflux](../../reactive/exploits/headers.html#webflux-headers-xss-protection)的应用程序定制默认值。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

一些浏览器内置了对过滤掉[反射 XSS 攻击](https://www.owasp.org/index.php/Testing_for_Reflected_Cross_site_scripting_(OWASP-DV-001)的支持。这绝不是万无一失的，但确实有助于 XSS 保护。

默认情况下，过滤通常是启用的，因此添加标题通常只会确保它已启用，并指示浏览器在检测到 XSS 攻击时该做什么。例如，过滤器可能会尝试以最不具侵入性的方式更改内容，以便仍然呈现所有内容。有时，这种类型的替换可以变成[XSS 本身的漏洞](https://hackademix.net/2009/11/21/ies-xss-filter-creates-xss-vulnerabilities/)。相反，最好是屏蔽内容，而不是试图修复它。 Spring 默认情况下，安全性使用以下头来阻止内容：

```
X-XSS-Protection: 1; mode=block
```

## 内容安全策略(CSP)

|   |参考相关章节，了解如何配置基于[servlet](../../servlet/exploits/headers.html#servlet-headers-csp)和[webflux](../../reactive/exploits/headers.html#webflux-headers-csp)的应用程序。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

[内容安全策略](https://www.w3.org/TR/CSP2/)是一种机制，Web 应用程序可以利用该机制来减轻内容注入漏洞，例如跨站点脚本。CSP 是一种声明性策略，它为 Web 应用程序的作者提供了一种工具，用于声明并最终通知客户机（用户代理）Web 应用程序期望从哪些源加载资源。

|   |内容安全策略并不是要解决所有的内容注入漏洞。<br/>相反，可以利用 CSP 来帮助减少内容注入攻击造成的危害。<br/>作为第一道防线，Web 应用程序作者应该验证其输入并对其输出进行编码。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

Web 应用程序可以通过在响应中包含以下 HTTP 头中的一个来使用 CSP:

* `Content-Security-Policy`

* `Content-Security-Policy-Report-Only`

这些头中的每一个都被用作向客户机交付安全策略的机制。安全策略包含一组安全策略指令，每个指令负责声明特定资源表示的限制。

例如，Web 应用程序可以声明它希望从特定的、受信任的源加载脚本，方法是在响应中包含以下头：

例 5。内容安全策略示例

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

试图从除`script-src`指令中声明的内容以外的其他来源加载脚本的行为将被 User-Agent 阻止。此外，如果[report-uri](https://www.w3.org/TR/CSP2/#directive-report-uri)指令是在安全策略中声明的，那么违反行为将由用户代理报告给声明的 URL。

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

例 6。带有 report-uri 的内容安全策略

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

[违规报告](https://www.w3.org/TR/CSP2/#violation-reports)是标准的 JSON 结构，可以由 Web 应用程序自己的 API 或公共托管的 CSP 违规报告服务捕获，例如，[https://report-uri.com/](https://report-uri.com/)。

`Content-Security-Policy-Report-Only`头为 Web 应用程序的作者和管理员提供了监视安全策略而不是强制执行它们的功能。此标头通常用于为站点进行试验和/或开发安全策略。当策略被认为有效时，可以使用`Content-Security-Policy`头字段来强制执行该策略。

给定以下响应头，策略声明脚本可以从两个可能的源中的一个加载。

例 7。仅提供内容安全策略报告

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

如果站点违反了此策略，通过尝试从*Evil.com*加载脚本，用户代理将向*报告-URI*指令指定的声明 URL 发送违规报告，但仍然允许违规资源加载。

将内容安全策略应用于 Web 应用程序通常是一项非常重要的工作。以下资源可以为你的站点提供进一步的帮助，帮助你制定有效的安全策略。

[内容安全策略介绍](https://www.html5rocks.com/en/tutorials/security/content-security-policy/)

[CSP 指南-Mozilla 开发者网络](https://developer.mozilla.org/en-US/docs/Web/Security/CSP)

[W3C 候选推荐](https://www.w3.org/TR/CSP2/)

## 推荐人政策

|   |参考相关章节，了解如何配置基于[servlet](../../servlet/exploits/headers.html#servlet-headers-referrer)和[webflux](../../reactive/exploits/headers.html#webflux-headers-referrer)的应用程序。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

[推荐人政策](https://www.w3.org/TR/referrer-policy)是一种机制，Web 应用程序可以利用它来管理 Referrer 字段，该字段包含用户所在的最后一页。

Spring Security 的方法是使用[推荐人政策](https://www.w3.org/TR/referrer-policy/)头，它提供不同的[policies](https://www.w3.org/TR/referrer-policy/#referrer-policies):

例 8。推荐人政策示例

```
Referrer-Policy: same-origin
```

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

## 特征策略

|   |参考相关章节，了解如何配置基于[servlet](../../servlet/exploits/headers.html#servlet-headers-feature)和[webflux](../../reactive/exploits/headers.html#webflux-headers-feature)的应用程序。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

[特征策略](https://wicg.github.io/feature-policy/)是一种机制，允许 Web 开发人员有选择地启用、禁用和修改浏览器中某些 API 和 Web 功能的行为。

例 9。功能策略示例

```
Feature-Policy: geolocation 'self'
```

通过功能策略，开发人员可以 OPT 到一组“策略”中，以便浏览器对整个站点中使用的特定功能进行强制执行。这些策略限制了站点可以访问哪些 API，或修改浏览器的某些功能的默认行为。

## 权限策略

|   |参考相关章节，了解如何配置基于[servlet](../../servlet/exploits/headers.html#servlet-headers-permissions)和[webflux](../../reactive/exploits/headers.html#webflux-headers-permissions)的应用程序。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

[权限策略](https://w3c.github.io/webappsec-permissions-policy/)是一种机制，允许 Web 开发人员有选择地启用、禁用和修改浏览器中某些 API 和 Web 功能的行为。

例 10。权限策略示例

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

通过权限策略，开发人员可以 OPT 到一组“策略”中，以便浏览器对整个站点中使用的特定功能进行强制执行。这些策略限制了站点可以访问哪些 API，或修改浏览器的某些功能的默认行为。

## 清除站点数据

|   |参考相关章节，了解如何配置基于[servlet](../../servlet/exploits/headers.html#servlet-headers-clear-site-data)和[webflux](../../reactive/exploits/headers.html#webflux-headers-clear-site-data)的应用程序。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

[清除站点数据](https://www.w3.org/TR/clear-site-data/)是一种机制，通过这种机制，当 HTTP 响应包含此标头时，可以删除任何浏览器端数据（cookie、本地存储等）：

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

这是一个很好的清理行动，执行注销。

## 自定义标头

|   |请参阅相关部分，以了解如何配置基于[servlet](../../servlet/exploits/headers.html#servlet-headers-custom)的应用程序。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------|

Spring 安全性有一些机制，可以方便地将更常见的安全性标题添加到应用程序中。然而，它也提供了钩子来支持添加自定义头。