Spring Security漏洞防护—HTTP 安全响应头

一、默认的 Security Header

Spring Security提供了 一套默认的安全HTTP响应头,以提供安全默认值。虽然这些头信息中的每一个都被认为是最佳实践,但应该注意的是,并不是所有的客户端都使用这些头信息,所以鼓励进行额外的测试。

你可以定制特定的header。例如,假设你想使用默认值,但你希望为 X-Frame-Options 指定 SAMEORIGIN。

你可以通过以下配置做到这一点。

Customize Default Security Headers

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.frameOptions(frameOptions -> frameOptions
      				.sameOrigin()
      			)
      		);
      	return http.build();
      }

    }

如果你不希望添加默认值,并希望明确控制应该使用什么,你可以禁用默认值。接下来的代码列表显示了如何做到这一点。

如果你使用Spring Security的配置,下面只添加了 Cache Control。

Customize Cache Control Headers

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			// do not use any default headers unless explicitly listed
      			.defaultsDisabled()
      			.cacheControl(withDefaults())
      		);
      	return http.build();
      }

    }

如果有必要,你可以通过以下配置禁用所有的HTTP安全响应头。

Disable All HTTP Security Headers

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers.disable());
      	return http.build();
      }

    }

二、Cache Control

Spring Security默认包括 Cache Control (缓存控制)头。

然而,如果你真的想缓存特定的响应,你的应用程序可以选择性地调用 HttpServletResponse.setHeader(String,String) 来覆盖Spring Security设置的头。你可以用它来确保内容(如CSS、JavaScript和图片)被正确缓存。

当你使用Spring Web MVC时,这通常是在你的配置中完成的。你可以在Spring参考文档的 静态资源 部分找到关于如何做到这一点的细节

如果有必要,你也可以禁用Spring Security的缓存控制HTTP响应头。

Cache Control Disabled

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.cacheControl(cache -> cache.disable())
      		);
      	return http.build();
      }

    }

三、Content Type Options

Spring Security默认包括 Content-Type 头。然而,你可以禁用它。

Content Type Options Disabled

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable())
      		);
      	return http.build();
      }

    }

四、HTTP Strict Transport Security (HSTS)

默认情况下,Spring Security 提供 Strict Transport Security 头。然而,你可以明确地定制结果。下面的例子明确地提供了HSTS。

Strict Transport Security

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.httpStrictTransportSecurity(hsts -> hsts
      				.includeSubDomains(true)
      				.preload(true)
      				.maxAgeInSeconds(31536000)
      			)
      		);
      	return http.build();
      }

    }

五、HTTP Public Key Pinning (HPKP)

Spring Security提供了对 HTTP公钥绑定(HTTP Public Key Pinning) 的servlet支持,但 不再推荐。

你可以通过以下配置启用HPKP头。

HTTP Public Key Pinning

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.httpPublicKeyPinning(hpkp -> hpkp
      				.includeSubDomains(true)
      				.reportUri("https://example.net/pkp-report")
      				.addSha256Pins("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=", "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=")
      			)
      		);
      	return http.build();
      }

    }

六、X-Frame-Options

默认情况下,Spring Security通过使用 X-Frame-Options 指示浏览器阻止反射的XSS攻击。

例如,以下配置指定Spring Security不应再指示浏览器阻止该内容。

X-Frame-Options: SAMEORIGIN

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.frameOptions(frameOptions -> frameOptions
      				.sameOrigin()
      			)
      		);
      	return http.build();
      }

    }

七、X-XSS-Protection

默认情况下,Spring Security 通过使用X-XSS-Protection header指示浏览器禁用 XSS Auditor。然而,你可以改变这个默认值。例如,下面的配置指定Spring Security指示兼容的浏览器启用过滤功能,并阻止该内容。

X-XSS-Protection Customization

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.xssProtection(xss -> xss
      				.headerValue(XXssProtectionHeaderWriter.HeaderValue.ENABLED_MODE_BLOCK)
      			)
      		);
      	return http.build();
      }

    }

八、Content Security Policy (CSP)

Spring Security并没有默认添加 Content Security Policy(内容安全策略),因为如果不了解应用程序的上下文,就不可能知道合理的默认。web应用程序作者必须声明安全策略(或策略),以便对受保护的资源进行强制执行或监控。

考虑以下安全策略。

Content Security Policy Example

复制代码
Content-Security-Policy: script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/

鉴于前面的安全策略,你可以启用CSP头。

Content Security Policy

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.contentSecurityPolicy(csp -> csp
      				.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
      			)
      		);
      	return http.build();
      }

    }

要启用 CSP report-only header,请提供以下配置。

Content Security Policy Report Only

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.contentSecurityPolicy(csp -> csp
      				.policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
      				.reportOnly()
      			)
      		);
      	return http.build();
      }

    }

九、Referrer Policy

Spring Security 默认不添加 Referrer Policy 头。你可以通过使用配置来启用 Referer Policy 头。

Referrer Policy

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.referrerPolicy(referrer -> referrer
      				.policy(ReferrerPolicy.SAME_ORIGIN)
      			)
      		);
      	return http.build();
      }

    }

十、Feature Policy

Spring Security 默认不添加 Feature Policy 头。考虑一下下面的 Feature-Policy 头。

Feature-Policy Example

复制代码
Feature-Policy: geolocation 'self'

你可以通过使用以下配置来启用前面的 feature policy 头

Feature-Policy

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.featurePolicy("geolocation 'self'")
      		);
      	return http.build();
      }

    }

十一、Permissions Policy

Spring Security 默认不添加 Permissions Policy 头。考虑一下下面的 Permissions-Policy 头。

Permissions-Policy Example

复制代码
Permissions-Policy: geolocation=(self)

你可以使用以下配置启用前面的 permissions policy 头。

Permissions-Policy

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.permissionsPolicy(permissions -> permissions
      				.policy("geolocation=(self)")
      			)
      		);
      	return http.build();
      }

    }

十二、清除网站数据(Clear Site Data)

Spring Security默认不添加 Clear-Site-Data 头。考虑一下下面的 Clear-Site-Data 头。

Clear-Site-Data Example

复制代码
Clear-Site-Data: "cache", "cookies"

你可以通过以下配置在注销时发送前面的 header。

Clear-Site-Data

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.logout((logout) -> logout
                  .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES)))
      		);
      	return http.build();
      }

    }

十三、自定义 Header

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

1、静态 Header

有时,你可能希望在你的应用程序中注入不支持的自定义安全header。考虑一下下面的自定义安全header。

复制代码
X-Custom-Security-Header: header-value

鉴于前面的 header 信息,你可以通过使用以下配置将 header 信息添加到响应中。

StaticHeadersWriter

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value"))
      		);
      	return http.build();
      }

    }

2、HeadersWriter

当命名空间或Java配置不支持你想要的header时,你可以创建一个自定义的 HeadersWriter 实例,甚至提供一个自定义的 HeadersWriter 实现。

下一个例子使用 XFrameOptionsHeaderWriter 的一个自定义实例。如果你想明确地配置 X-Frame-Options,你可以用下面的配置来实现。

Headers Writer

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	http
      		// ...
      		.headers(headers -> headers
      			.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
      		);
      	return http.build();
      }

    }

3、DelegatingRequestMatcherHeaderWriter

有时,你可能想只为某些请求写一个header。例如,也许你只想保护你的登录页面.。你可以使用 DelegatingRequestMatcherHeaderWriter 来做到这一点。

下面的配置例子使用 DelegatingRequestMatcherHeaderWriter。

DelegatingRequestMatcherHeaderWriter Java Configuration

  • Java

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {

    复制代码
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
      	RequestMatcher matcher = new AntPathRequestMatcher("/login");
      	DelegatingRequestMatcherHeaderWriter headerWriter =
      		new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
      	http
      		// ...
      		.headers(headers -> headers
      			.frameOptions(frameOptions -> frameOptions.disable())
      			.addHeaderWriter(headerWriter)
      		);
      	return http.build();
      }

    }

相关推荐
学传打活4 天前
【边打字.边学昆仑正义文化】_进阶篇5 宇宙星系的运转(续1)
微信公众平台·1024程序员节·汉字·昆仑正义文化
fangzhanpeng16812 天前
快速掌握C#语言基础知识点(1.基础数据类型)
开发语言·c#·1024程序员节
无己心14 天前
面向多平台 AI 搜索引擎的适配层架构设计
前端·人工智能·搜索引擎·ai·1024程序员节
u01030552720 天前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u01030552721 天前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝22 天前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u01030552722 天前
Java图像处理实战指南
人工智能·1024程序员节
u01030552723 天前
Java AWT鼠标事件全解析
人工智能·1024程序员节
u01030552725 天前
Java实用类应用精讲
人工智能·1024程序员节
u01030552725 天前
Java I/O核心操作实战
人工智能·1024程序员节