17. 默认安全标题

Spring Security 允许用户轻松注入默认的安全 Headers,以帮助保护其应用程序。 Spring Security 的默认值为包含以下 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: 1; mode=block

Note

仅在 HTTPS 请求上添加严格传输安全性

有关这些标题中的每个标题的更多详细信息,请参阅相应的部分:

虽然这些 Headers 中的每一个均被视为最佳实践,但应注意,并非所有 Client 端都使用 Headers,因此鼓励进行其他测试。

您可以自定义特定的标题。例如,假设希望您的 HTTP 响应 Headers 如下所示:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block

具体来说,您希望所有默认 Headers 都具有以下自定义设置:

您可以使用以下 Java 配置轻松完成此操作:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .hsts().disable()
            .frameOptions().mode(Mode.SAMEORIGIN);
    return http.build();
}

如果您不想添加默认值,并且希望对应使用的内容进行明确控制,则可以禁用默认值。下面提供了基于 Java 和 XML 的配置示例:

如有必要,可以使用以下 Java 配置禁用所有 HTTP 安全响应 Headers:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .disable();
    return http.build();
}

17.1 缓存控制

过去,Spring Security 要求您为 Web 应用程序提供自己的缓存控件。当时看来这是合理的,但浏览器缓存已 Developing 为包括用于安全连接的缓存。这意味着用户可以查看经过身份验证的页面,然后注销,然后恶意用户可以使用浏览器历史记录来查看缓存的页面。为了缓解这种情况,Spring Security 添加了缓存控制支持,默认情况下会将以下 Headers 插入响应中。

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

如果您确实想缓存特定的响应,则您的应用程序可以有选择地设置缓存控制 Headers 以覆盖 Spring Security 设置的 Headers。这对于确保正确缓存 CSS,JavaScript 和图像之类的内容很有用。

您还可以使用以下 Java 配置禁用缓存控制:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .cache().disable();
    return http.build();
}

17.2Content Type 选项

历史上,包括 Internet Explorer 在内的浏览器都会尝试使用content sniffing来猜测请求的 Content Type。这允许浏览器通过猜测未指定 Content Type 的资源上的 Content Type 来改善用户体验。例如,如果浏览器遇到一个未指定 Content Type 的 JavaScript 文件,它将能够猜测该 Content Type 然后执行它。

Note

==允许上传内容时,还有许多其他事情(即,仅在不同的域中显示文档,确保设置了 Content-TypeHeaders,清理文档等)。但是,这些措施不在 Spring Security 提供的范围之内。同样重要的是要指出在禁用内容嗅探时,必须指定 Content Type 才能使内容正常工作。 ==

内容嗅探的问题在于,这允许恶意用户使用多义标记(即,可以作为多种 Content Type 有效的文件)执行 XSS 攻击。例如,某些网站可能允许用户向网站提交有效的附言文档并进行查看。恶意用户可能会创建后记文档也是有效的 JavaScript 文件并对其执行 XSS 攻击。

可以通过在响应中添加以下 Headers 来禁用内容嗅探:

X-Content-Type-Options: nosniff

与缓存控制元素一样,默认情况下会添加 nosniff 指令。但是,如果需要禁用标题,则可以使用以下内容:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .contentTypeOptions().disable();
    return http.build();
}

17.3 HTTP 严格传输安全性(HSTS)

当您 Importing 银行的网站时,您 Importingmybank.example.com 还是 Importinghttps://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。这大大降低了发生中间人攻击的可能性。

Note

==按照RFC6797,HSTSHeaders 仅注入 HTTPS 响应中。为了使浏览器能够确认 Headers,浏览器必须首先信任对用于构建连接的 SSL 证书(不仅仅是 SSL 证书)进行签名的 CA。 ==

将站点标记为 HSTS 主机的一种方法是将主机预加载到浏览器中。另一个方法是在响应中添加“ Strict-Transport-Security”Headers。例如,以下内容将指示浏览器将域视为一年的 HSTS 主机(一年大约 31536000 秒):

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

可选的 includeSubDomains 指令指示 Spring Security 子域(即 secure.mybank.example.com)也应被视为 HSTS 域。

与其他头文件一样,Spring Security 默认添加 HSTS。您可以使用 Java 配置自定义 HSTSHeaders:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .hsts()
                .includeSubdomains(true)
                .maxAge(Duration.ofDays(365));
    return http.build();
}

17.4 X-Frame-Options

允许将您的网站添加到框架可能是一个安全问题。例如,使用聪明的 CSS 样式用户可能会被诱骗点击他们不想要的内容(video demo)。例如,登录到其银行的用户可以单击将按钮授予其他用户访问权限。这种攻击称为Clickjacking

Note

==处理点击劫持的另一种现代方法是使用第 17.6 节“内容安全策略(CSP)”。 ==

有许多方法可以缓解点击劫持攻击。例如,要保护旧版浏览器免受点击劫持攻击,可以使用帧破码。虽然不完美,但是对于传统浏览器而言,破帧代码是最好的选择。

解决点击劫持的更现代方法是使用X-Frame-OptionsHeaders:

X-Frame-Options: DENY

X-Frame-Options 响应 Headers 指示浏览器阻止响应中带有此 Headers 的任何网站呈现在框架中。默认情况下,Spring Security 禁用 iframe 中的呈现。

您可以使用以下命令使用 Java 配置来自定义 X-Frame-Options:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .frameOptions()
                .mode(SAMEORIGIN);
    return http.build();
}

17.5 X-XSS-Protection

一些浏览器内置了对过滤反映的 XSS 攻击的支持。这绝非万无一失,但确实有助于 XSS 保护。

通常默认情况下会启用过滤,因此添加 Headers 通常只会确保 Headers 已启用,并指示浏览器在检测到 XSS 攻击时应采取的措施。例如,过滤器可能会尝试以最小侵入性的方式更改内容以仍然呈现所有内容。有时,这种替换可以成为XSS 漏洞本身。相反,最好是阻止内容,而不要尝试对其进行修复。为此,我们可以添加以下 Headers:

X-XSS-Protection: 1; mode=block

默认情况下包含此 Headers。但是,我们可以使用以下内容使用 Java 配置进行自定义:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .xssProtection()
                .disable();
    return http.build();
}

17.6 内容安全 Policy(CSP)

内容安全 Policy(CSP)是 Web 应用程序可以利用的一种机制来减轻内容注入漏洞,例如跨站点脚本(XSS)。 CSP 是一种声明性策略,为 Web 应用程序作者提供了一种工具,可以声明该 Web 应用程序希望从中加载资源的来源,并最终将这些信息通知 Client 端(用户代理)。

Note

==内容安全策略并非旨在解决所有内容注入漏洞。取而代之的是,可以利用 CSP 帮助减少内容注入攻击所造成的危害。作为第一道防线,Web 应用程序作者应验证其 Importing 并对输出进行编码。 ==

Web 应用程序可以通过在响应中包括以下 HTTPHeaders 之一来使用 CSP:

  • Content-Security-Policy

  • Content-Security-Policy-Report-Only

这些 Headers 中的每一个都用作向 Client 端传递 *安全策略 *的机制。安全策略包含一组 *安全策略指令 (例如 script-src object-src *),每个指令负责声明对特定资源表示形式的限制。

例如,Web 应用程序可以通过在响应中包括以下 Headers 来声明它希望从特定的受信任源中加载脚本:

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

尝试从* script-src *指令中未声明的其他来源加载脚本的尝试将被用户代理阻止。此外,如果在安全策略中声明了report-uri指令,则用户代理会将违规报告到声明的 URL。

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

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

Violation reports是标准 JSON 结构,可以由 Web 应用程序自己的 API 或由公共托管的 CSP 违规报告服务(例如REPORT-URI)捕获。

*** Content-Security-Policy-Report-Only** Headers 为 Web 应用程序作者和 Management 员提供了监视安全策略而不是强制执行这些策略的功能。该标题通常在试验和/或开发站点的安全策略时使用。当某个策略被认为有效时,可以通过使用 Content-Security-Policy *Headers 字段来实施该策略。

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

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

如果网站违反了此 Policy,则通过尝试从* evil.com 加载脚本,用户代理会将违规报告发送到 report-uri *指令指定的声明的 URL,但仍允许违规资源尽管如此。

17.6.1 配置内容安全策略

重要的是要注意,Spring Security *默认不添加 * Content Security Policy。 Web 应用程序作者必须声明安全策略以强制执行和/或监视受保护的资源。

例如,给定以下安全策略:

script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/

您可以使用 Java 配置启用 CSPHeaders,如下所示:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/");
    return http.build();
}

要启用 CSP *'report-only'*Headers,请提供以下 Java 配置:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
            .reportOnly();
    return http.build();
}

17.6.2 其他资源

将内容安全策略应用于 Web 应用程序通常是一项艰巨的任务。以下资源可以为您的站点制定有效的安全策略提供进一步的帮助。

内容安全策略简介

CSP 指南-Mozilla 开发人员网络

W3C 候选人推荐

17.7 推荐人 Policy

Referrer Policy是一种机制,Web 应用程序可以利用该机制来 Management 引荐来源网址字段,该字段包含用户所在的最后一页。

Spring Security 的方法是使用Referrer PolicyHeaders,它提供了不同的policies

Referrer-Policy: same-origin

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

17.7.1 配置引荐来源网址策略

Spring Security *不会添加 * Referrer PolicyHeaders 默认情况下。

您可以使用 Java 配置启用 Referrer-PolicyHeaders,如下所示:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .referrerPolicy(ReferrerPolicy.SAME_ORIGIN);
    return http.build();
}

17.8 功能 Policy

Feature Policy是一种机制,允许 Web 开发人员在浏览器中选择性地启用,禁用和修改某些 API 和 Web 功能的行为。

Feature-Policy: geolocation 'self'

借助功能策略,开发人员可以为浏览器选择一套“策略”,以实施整个站点中使用的特定功能。这些策略限制了网站可以访问或修改某些功能的浏览器默认行为的 API。

17.8.1 配置功能策略

Spring Security *默认不添加 * Feature PolicyHeaders。

您可以使用 Java 配置启用 Feature-PolicyHeaders,如下所示:

@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http
        // ...
        .headers()
            .featurePolicy("geolocation 'self'");
    return http.build();
}