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


    一、默认的 Security Header

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

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

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

    Customize Default Security Headers

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .frameOptions(frameOptions -> frameOptions
    10. .sameOrigin()
    11. )
    12. );
    13. return http.build();
    14. }
    15. }

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

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

    Customize Cache Control Headers

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. // do not use any default headers unless explicitly listed
    10. .defaultsDisabled()
    11. .cacheControl(withDefaults())
    12. );
    13. return http.build();
    14. }
    15. }

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

    Disable All HTTP Security Headers

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers.disable());
    9. return http.build();
    10. }
    11. }

    二、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
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .cacheControl(cache -> cache.disable())
    10. );
    11. return http.build();
    12. }
    13. }

    三、Content Type Options

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

    Content Type Options Disabled

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable())
    10. );
    11. return http.build();
    12. }
    13. }

    四、HTTP Strict Transport Security (HSTS)

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

    Strict Transport Security

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .httpStrictTransportSecurity(hsts -> hsts
    10. .includeSubDomains(true)
    11. .preload(true)
    12. .maxAgeInSeconds(31536000)
    13. )
    14. );
    15. return http.build();
    16. }
    17. }

    五、HTTP Public Key Pinning (HPKP)

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

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

    HTTP Public Key Pinning

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .httpPublicKeyPinning(hpkp -> hpkp
    10. .includeSubDomains(true)
    11. .reportUri("https://example.net/pkp-report")
    12. .addSha256Pins("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=", "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=")
    13. )
    14. );
    15. return http.build();
    16. }
    17. }

    六、X-Frame-Options

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

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

    X-Frame-Options: SAMEORIGIN

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .frameOptions(frameOptions -> frameOptions
    10. .sameOrigin()
    11. )
    12. );
    13. return http.build();
    14. }
    15. }

    七、X-XSS-Protection

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

    X-XSS-Protection Customization

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .xssProtection(xss -> xss
    10. .headerValue(XXssProtectionHeaderWriter.HeaderValue.ENABLED_MODE_BLOCK)
    11. )
    12. );
    13. return http.build();
    14. }
    15. }

    八、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
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .contentSecurityPolicy(csp -> csp
    10. .policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
    11. )
    12. );
    13. return http.build();
    14. }
    15. }

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

    Content Security Policy Report Only

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .contentSecurityPolicy(csp -> csp
    10. .policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
    11. .reportOnly()
    12. )
    13. );
    14. return http.build();
    15. }
    16. }

    九、Referrer Policy

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

    Referrer Policy

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .referrerPolicy(referrer -> referrer
    10. .policy(ReferrerPolicy.SAME_ORIGIN)
    11. )
    12. );
    13. return http.build();
    14. }
    15. }

    十、Feature Policy

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

    Feature-Policy Example

    Feature-Policy: geolocation 'self'

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

    Feature-Policy

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .featurePolicy("geolocation 'self'")
    10. );
    11. return http.build();
    12. }
    13. }

    十一、Permissions Policy

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

    Permissions-Policy Example

    Permissions-Policy: geolocation=(self)

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

    Permissions-Policy

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .permissionsPolicy(permissions -> permissions
    10. .policy("geolocation=(self)")
    11. )
    12. );
    13. return http.build();
    14. }
    15. }

    十二、清除网站数据(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
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .logout((logout) -> logout
    9. .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES)))
    10. );
    11. return http.build();
    12. }
    13. }

    十三、自定义 Header

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

    1、静态 Header

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

    X-Custom-Security-Header: header-value

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

    StaticHeadersWriter

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value"))
    10. );
    11. return http.build();
    12. }
    13. }

    2、HeadersWriter

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

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

    Headers Writer

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. http
    7. // ...
    8. .headers(headers -> headers
    9. .addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
    10. );
    11. return http.build();
    12. }
    13. }

    3、DelegatingRequestMatcherHeaderWriter

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

    下面的配置例子使用 DelegatingRequestMatcherHeaderWriter。

    DelegatingRequestMatcherHeaderWriter Java Configuration

    • Java
    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig {
    4. @Bean
    5. public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    6. RequestMatcher matcher = new AntPathRequestMatcher("/login");
    7. DelegatingRequestMatcherHeaderWriter headerWriter =
    8. new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
    9. http
    10. // ...
    11. .headers(headers -> headers
    12. .frameOptions(frameOptions -> frameOptions.disable())
    13. .addHeaderWriter(headerWriter)
    14. );
    15. return http.build();
    16. }
    17. }

  • 相关阅读:
    libevent库bufferevent事件实现socket通信
    Python 潮流周刊第 46 期(摘要)+ 赠书 7 本
    【COMP305 LEC6 LEC 7】
    【调制解调】SSB 单边带调幅
    Cisco简单配置(十八)—OSPF
    前端学习第三天-css基础
    Redis系列-四种部署方式-单机部署+主从模式+哨兵模式【7】
    C++ Primer学习笔记-----第三章:字符串、向量、数组
    AERMOD模型大气环境影响评价
    用Flask构建一个AI翻译服务
  • 原文地址:https://blog.csdn.net/leesinbad/article/details/134008900