exploits.adoc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. = Exploit Protection Migrations
  2. The following steps relate to changes around how to configure CSRF.
  3. == Defer Loading CsrfToken
  4. In Spring Security 5, the default behavior is that the `CsrfToken` will be loaded on every request.
  5. This means that in a typical setup, the `HttpSession` must be read for every request even if it is unnecessary.
  6. In Spring Security 6, the default is that the lookup of the `CsrfToken` will be deferred until it is needed.
  7. To opt into the new Spring Security 6 default, the following configuration can be used.
  8. .Defer Loading `CsrfToken`
  9. ====
  10. .Java
  11. [source,java,role="primary"]
  12. ----
  13. @Bean
  14. DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
  15. CsrfTokenRequestAttributeHandler requestHandler = new CsrfTokenRequestAttributeHandler();
  16. // set the name of the attribute the CsrfToken will be populated on
  17. requestHandler.setCsrfRequestAttributeName("_csrf");
  18. http
  19. // ...
  20. .csrf((csrf) -> csrf
  21. .csrfTokenRequestHandler(requestHandler)
  22. );
  23. return http.build();
  24. }
  25. ----
  26. .Kotlin
  27. [source,kotlin,role="secondary"]
  28. ----
  29. @Bean
  30. open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
  31. val requestHandler = CsrfTokenRequestAttributeHandler()
  32. // set the name of the attribute the CsrfToken will be populated on
  33. requestHandler.setCsrfRequestAttributeName("_csrf")
  34. http {
  35. csrf {
  36. csrfTokenRequestHandler = requestHandler
  37. }
  38. }
  39. return http.build()
  40. }
  41. ----
  42. .XML
  43. [source,xml,role="secondary"]
  44. ----
  45. <http>
  46. <!-- ... -->
  47. <csrf request-handler-ref="requestHandler"/>
  48. </http>
  49. <b:bean id="requestHandler"
  50. class="org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler"
  51. p:csrfRequestAttributeName="_csrf"/>
  52. ----
  53. ====
  54. If this breaks your application, then you can explicitly opt into the 5.8 defaults using the following configuration:
  55. .Explicit Configure `CsrfToken` with 5.8 Defaults
  56. ====
  57. .Java
  58. [source,java,role="primary"]
  59. ----
  60. @Bean
  61. DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
  62. CsrfTokenRequestAttributeHandler requestHandler = new CsrfTokenRequestAttributeHandler();
  63. // set the name of the attribute the CsrfToken will be populated on
  64. requestHandler.setCsrfRequestAttributeName(null);
  65. http
  66. // ...
  67. .csrf((csrf) -> csrf
  68. .csrfTokenRequestHandler(requestHandler)
  69. );
  70. return http.build();
  71. }
  72. ----
  73. .Kotlin
  74. [source,kotlin,role="secondary"]
  75. ----
  76. @Bean
  77. open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
  78. val requestHandler = CsrfTokenRequestAttributeHandler()
  79. // set the name of the attribute the CsrfToken will be populated on
  80. requestHandler.setCsrfRequestAttributeName(null)
  81. http {
  82. csrf {
  83. csrfTokenRequestHandler = requestHandler
  84. }
  85. }
  86. return http.build()
  87. }
  88. ----
  89. .XML
  90. [source,xml,role="secondary"]
  91. ----
  92. <http>
  93. <!-- ... -->
  94. <csrf request-handler-ref="requestHandler"/>
  95. </http>
  96. <b:bean id="requestHandler"
  97. class="org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler">
  98. <b:property name="csrfRequestAttributeName">
  99. <b:null/>
  100. </b:property>
  101. </b:bean>
  102. ----
  103. ====
  104. == Protect against CSRF BREACH
  105. If the steps for <<Defer Loading CsrfToken>> work for you, then you can also opt into Spring Security 6's default support for BREACH protection of the `CsrfToken` using the following configuration:
  106. .`CsrfToken` BREACH Protection
  107. ====
  108. .Java
  109. [source,java,role="primary"]
  110. ----
  111. @Bean
  112. DefaultSecurityFilterChain springSecurity(HttpSecurity http) throws Exception {
  113. XorCsrfTokenRequestAttributeHandler requestHandler = new XorCsrfTokenRequestAttributeHandler();
  114. // set the name of the attribute the CsrfToken will be populated on
  115. requestHandler.setCsrfRequestAttributeName("_csrf");
  116. http
  117. // ...
  118. .csrf((csrf) -> csrf
  119. .csrfTokenRequestHandler(requestHandler)
  120. );
  121. return http.build();
  122. }
  123. ----
  124. .Kotlin
  125. [source,kotlin,role="secondary"]
  126. ----
  127. @Bean
  128. open fun springSecurity(http: HttpSecurity): SecurityFilterChain {
  129. val requestHandler = XorCsrfTokenRequestAttributeHandler()
  130. // set the name of the attribute the CsrfToken will be populated on
  131. requestHandler.setCsrfRequestAttributeName("_csrf")
  132. http {
  133. csrf {
  134. csrfTokenRequestHandler = requestHandler
  135. }
  136. }
  137. return http.build()
  138. }
  139. ----
  140. .XML
  141. [source,xml,role="secondary"]
  142. ----
  143. <http>
  144. <!-- ... -->
  145. <csrf request-handler-ref="requestHandler"/>
  146. </http>
  147. <b:bean id="requestHandler"
  148. class="org.springframework.security.web.csrf.XorCsrfTokenRequestAttributeHandler"
  149. p:csrfRequestAttributeName="_csrf"/>
  150. ----
  151. ====