headers.adoc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149
  1. [[servlet-headers]]
  2. = Security HTTP Response Headers
  3. xref:features/exploits/headers.adoc#headers[Security HTTP Response Headers] can be used to increase the security of web applications.
  4. This section is dedicated to servlet based support for Security HTTP Response Headers.
  5. [[servlet-headers-default]]
  6. == Default Security Headers
  7. Spring Security provides a xref:features/exploits/headers.adoc#headers-default[default set of Security HTTP Response Headers] to provide secure defaults.
  8. While each of these headers are considered best practice, it should be noted that not all clients utilize the headers, so additional testing is encouraged.
  9. You can customize specific headers.
  10. For example, assume that you want the defaults except you wish to specify `SAMEORIGIN` for <<servlet-headers-frame-options,X-Frame-Options>>.
  11. You can easily do this with the following Configuration:
  12. .Customize Default Security Headers
  13. ====
  14. .Java
  15. [source,java,role="primary"]
  16. ----
  17. @EnableWebSecurity
  18. public class WebSecurityConfig extends
  19. WebSecurityConfigurerAdapter {
  20. @Override
  21. protected void configure(HttpSecurity http) {
  22. http
  23. // ...
  24. .headers(headers -> headers
  25. .frameOptions(frameOptions -> frameOptions
  26. .sameOrigin()
  27. )
  28. );
  29. }
  30. }
  31. ----
  32. .XML
  33. [source,xml,role="secondary"]
  34. ----
  35. <http>
  36. <!-- ... -->
  37. <headers>
  38. <frame-options policy="SAMEORIGIN" />
  39. </headers>
  40. </http>
  41. ----
  42. .Kotlin
  43. [source,kotlin,role="secondary"]
  44. ----
  45. @EnableWebSecurity
  46. class SecurityConfig : WebSecurityConfigurerAdapter() {
  47. override fun configure(http: HttpSecurity) {
  48. http {
  49. // ...
  50. headers {
  51. frameOptions {
  52. sameOrigin = true
  53. }
  54. }
  55. }
  56. }
  57. }
  58. ----
  59. ====
  60. If you do not want the defaults to be added and want explicit control over what should be used, you can disable the defaults.
  61. An example is provided below:
  62. If you are using Spring Security's Configuration the following will only add xref:features/exploits/headers.adoc#headers-cache-control[Cache Control].
  63. .Customize Cache Control Headers
  64. ====
  65. .Java
  66. [source,java,role="primary"]
  67. ----
  68. @EnableWebSecurity
  69. public class WebSecurityConfig extends
  70. WebSecurityConfigurerAdapter {
  71. @Override
  72. protected void configure(HttpSecurity http) throws Exception {
  73. http
  74. // ...
  75. .headers(headers -> headers
  76. // do not use any default headers unless explicitly listed
  77. .defaultsDisabled()
  78. .cacheControl(withDefaults())
  79. );
  80. }
  81. }
  82. ----
  83. .XML
  84. [source,xml,role="secondary"]
  85. ----
  86. <http>
  87. <!-- ... -->
  88. <headers defaults-disabled="true">
  89. <cache-control/>
  90. </headers>
  91. </http>
  92. ----
  93. .Kotlin
  94. [source,kotlin,role="secondary"]
  95. ----
  96. @EnableWebSecurity
  97. class SecurityConfig : WebSecurityConfigurerAdapter() {
  98. override fun configure(http: HttpSecurity) {
  99. http {
  100. // ...
  101. headers {
  102. // do not use any default headers unless explicitly listed
  103. defaultsDisabled = true
  104. cacheControl {
  105. }
  106. }
  107. }
  108. }
  109. }
  110. ----
  111. ====
  112. If necessary, you can disable all of the HTTP Security response headers with the following Configuration:
  113. .Disable All HTTP Security Headers
  114. ====
  115. .Java
  116. [source,java,role="primary"]
  117. ----
  118. @EnableWebSecurity
  119. public class WebSecurityConfig extends
  120. WebSecurityConfigurerAdapter {
  121. @Override
  122. protected void configure(HttpSecurity http) throws Exception {
  123. http
  124. // ...
  125. .headers(headers -> headers.disable());
  126. }
  127. }
  128. ----
  129. .XML
  130. [source,xml,role="secondary"]
  131. ----
  132. <http>
  133. <!-- ... -->
  134. <headers disabled="true" />
  135. </http>
  136. ----
  137. .Kotlin
  138. [source,kotlin,role="secondary"]
  139. ----
  140. @EnableWebSecurity
  141. class SecurityConfig : WebSecurityConfigurerAdapter() {
  142. override fun configure(http: HttpSecurity) {
  143. http {
  144. // ...
  145. headers {
  146. disable()
  147. }
  148. }
  149. }
  150. }
  151. ----
  152. ====
  153. [[servlet-headers-cache-control]]
  154. == Cache Control
  155. Spring Security includes xref:features/exploits/headers.adoc#headers-cache-control[Cache Control] headers by default.
  156. However, if you actually want to cache specific responses, your application can selectively invoke https://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html#setHeader(java.lang.String,java.lang.String)[HttpServletResponse.setHeader(String,String)] to override the header set by Spring Security.
  157. This is useful to ensure things like CSS, JavaScript, and images are properly cached.
  158. When using Spring Web MVC, this is typically done within your configuration.
  159. Details on how to do this can be found in the https://docs.spring.io/spring/docs/5.0.0.RELEASE/spring-framework-reference/web.html#mvc-config-static-resources[Static Resources] portion of the Spring Reference documentation
  160. If necessary, you can also disable Spring Security's cache control HTTP response headers.
  161. .Cache Control Disabled
  162. ====
  163. .Java
  164. [source,java,role="primary"]
  165. ----
  166. @Configuration
  167. @EnableWebSecurity
  168. public class WebSecurityConfig extends
  169. WebSecurityConfigurerAdapter {
  170. @Override
  171. protected void configure(HttpSecurity http) {
  172. http
  173. // ...
  174. .headers(headers -> headers
  175. .cacheControl(cache -> cache.disable())
  176. );
  177. }
  178. }
  179. ----
  180. .XML
  181. [source,xml,role="secondary"]
  182. ----
  183. <http>
  184. <!-- ... -->
  185. <headers>
  186. <cache-control disabled="true"/>
  187. </headers>
  188. </http>
  189. ----
  190. .Kotlin
  191. [source,kotlin,role="secondary"]
  192. ----
  193. @EnableWebSecurity
  194. class SecurityConfig : WebSecurityConfigurerAdapter() {
  195. override fun configure(http: HttpSecurity) {
  196. http {
  197. headers {
  198. cacheControl {
  199. disable()
  200. }
  201. }
  202. }
  203. }
  204. }
  205. ----
  206. ====
  207. [[servlet-headers-content-type-options]]
  208. == Content Type Options
  209. Spring Security includes xref:features/exploits/headers.adoc#headers-content-type-options[Content-Type] headers by default.
  210. However, you can disable it with:
  211. .Content Type Options Disabled
  212. ====
  213. .Java
  214. [source,java,role="primary"]
  215. ----
  216. @Configuration
  217. @EnableWebSecurity
  218. public class WebSecurityConfig extends
  219. WebSecurityConfigurerAdapter {
  220. @Override
  221. protected void configure(HttpSecurity http) {
  222. http
  223. // ...
  224. .headers(headers -> headers
  225. .contentTypeOptions(contentTypeOptions -> contentTypeOptions.disable())
  226. );
  227. }
  228. }
  229. ----
  230. .XML
  231. [source,xml,role="secondary"]
  232. ----
  233. <http>
  234. <!-- ... -->
  235. <headers>
  236. <content-type-options disabled="true"/>
  237. </headers>
  238. </http>
  239. ----
  240. .Kotlin
  241. [source,kotlin,role="secondary"]
  242. ----
  243. @EnableWebSecurity
  244. class SecurityConfig : WebSecurityConfigurerAdapter() {
  245. override fun configure(http: HttpSecurity) {
  246. http {
  247. headers {
  248. contentTypeOptions {
  249. disable()
  250. }
  251. }
  252. }
  253. }
  254. }
  255. ----
  256. ====
  257. [[servlet-headers-hsts]]
  258. == HTTP Strict Transport Security (HSTS)
  259. Spring Security provides the xref:features/exploits/headers.adoc#headers-hsts[Strict Transport Security] header by default.
  260. However, you can customize the results explicitly.
  261. For example, the following is an example of explicitly providing HSTS:
  262. .Strict Transport Security
  263. ====
  264. .Java
  265. [source,java,role="primary"]
  266. ----
  267. @EnableWebSecurity
  268. public class WebSecurityConfig extends
  269. WebSecurityConfigurerAdapter {
  270. @Override
  271. protected void configure(HttpSecurity http) throws Exception {
  272. http
  273. // ...
  274. .headers(headers -> headers
  275. .httpStrictTransportSecurity(hsts -> hsts
  276. .includeSubDomains(true)
  277. .preload(true)
  278. .maxAgeInSeconds(31536000)
  279. )
  280. );
  281. }
  282. }
  283. ----
  284. .XML
  285. [source,xml,role="secondary"]
  286. ----
  287. <http>
  288. <!-- ... -->
  289. <headers>
  290. <hsts
  291. include-subdomains="true"
  292. max-age-seconds="31536000"
  293. preload="true" />
  294. </headers>
  295. </http>
  296. ----
  297. .Kotlin
  298. [source,kotlin,role="secondary"]
  299. ----
  300. @EnableWebSecurity
  301. class SecurityConfig : WebSecurityConfigurerAdapter() {
  302. override fun configure(http: HttpSecurity) {
  303. http {
  304. headers {
  305. httpStrictTransportSecurity {
  306. includeSubDomains = true
  307. preload = true
  308. maxAgeInSeconds = 31536000
  309. }
  310. }
  311. }
  312. }
  313. }
  314. ----
  315. ====
  316. [[servlet-headers-hpkp]]
  317. == HTTP Public Key Pinning (HPKP)
  318. For passivity reasons, Spring Security provides servlet support for xref:features/exploits/headers.adoc#headers-hpkp[HTTP Public Key Pinning] but it is xref:features/exploits/headers.adoc#headers-hpkp-deprecated[no longer recommended].
  319. You can enable HPKP headers with the following Configuration:
  320. .HTTP Public Key Pinning
  321. ====
  322. .Java
  323. [source,java,role="primary"]
  324. ----
  325. @EnableWebSecurity
  326. public class WebSecurityConfig extends
  327. WebSecurityConfigurerAdapter {
  328. @Override
  329. protected void configure(HttpSecurity http) throws Exception {
  330. http
  331. // ...
  332. .headers(headers -> headers
  333. .httpPublicKeyPinning(hpkp -> hpkp
  334. .includeSubDomains(true)
  335. .reportUri("https://example.net/pkp-report")
  336. .addSha256Pins("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=", "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=")
  337. )
  338. );
  339. }
  340. }
  341. ----
  342. .XML
  343. [source,xml,role="secondary"]
  344. ----
  345. <http>
  346. <!-- ... -->
  347. <headers>
  348. <hpkp
  349. include-subdomains="true"
  350. report-uri="https://example.net/pkp-report">
  351. <pins>
  352. <pin algorithm="sha256">d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=</pin>
  353. <pin algorithm="sha256">E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=</pin>
  354. </pins>
  355. </hpkp>
  356. </headers>
  357. </http>
  358. ----
  359. .Kotlin
  360. [source,kotlin,role="secondary"]
  361. ----
  362. @EnableWebSecurity
  363. class SecurityConfig : WebSecurityConfigurerAdapter() {
  364. override fun configure(http: HttpSecurity) {
  365. http {
  366. headers {
  367. httpPublicKeyPinning {
  368. includeSubDomains = true
  369. reportUri = "https://example.net/pkp-report"
  370. pins = mapOf("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=" to "sha256",
  371. "E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" to "sha256")
  372. }
  373. }
  374. }
  375. }
  376. }
  377. ----
  378. ====
  379. [[servlet-headers-frame-options]]
  380. == X-Frame-Options
  381. By default, Spring Security disables rendering within an iframe using xref:features/exploits/headers.adoc#headers-frame-options[X-Frame-Options].
  382. You can customize frame options to use the same origin within a Configuration using the following:
  383. .X-Frame-Options: SAMEORIGIN
  384. ====
  385. .Java
  386. [source,java,role="primary"]
  387. ----
  388. @EnableWebSecurity
  389. public class WebSecurityConfig extends
  390. WebSecurityConfigurerAdapter {
  391. @Override
  392. protected void configure(HttpSecurity http) throws Exception {
  393. http
  394. // ...
  395. .headers(headers -> headers
  396. .frameOptions(frameOptions -> frameOptions
  397. .sameOrigin()
  398. )
  399. );
  400. }
  401. }
  402. ----
  403. .XML
  404. [source,xml,role="secondary"]
  405. ----
  406. <http>
  407. <!-- ... -->
  408. <headers>
  409. <frame-options
  410. policy="SAMEORIGIN" />
  411. </headers>
  412. </http>
  413. ----
  414. .Kotlin
  415. [source,kotlin,role="secondary"]
  416. ----
  417. @EnableWebSecurity
  418. class SecurityConfig : WebSecurityConfigurerAdapter() {
  419. override fun configure(http: HttpSecurity) {
  420. http {
  421. headers {
  422. frameOptions {
  423. sameOrigin = true
  424. }
  425. }
  426. }
  427. }
  428. }
  429. ----
  430. ====
  431. [[servlet-headers-xss-protection]]
  432. == X-XSS-Protection
  433. By default, Spring Security instructs browsers to block reflected XSS attacks using the <<headers-xss-protection,X-XSS-Protection header>.
  434. However, you can change this default.
  435. For example, the following Configuration specifies that Spring Security should no longer instruct browsers to block the content:
  436. .X-XSS-Protection Customization
  437. ====
  438. .Java
  439. [source,java,role="primary"]
  440. ----
  441. @EnableWebSecurity
  442. public class WebSecurityConfig extends
  443. WebSecurityConfigurerAdapter {
  444. @Override
  445. protected void configure(HttpSecurity http) throws Exception {
  446. http
  447. // ...
  448. .headers(headers -> headers
  449. .xssProtection(xss -> xss
  450. .block(false)
  451. )
  452. );
  453. }
  454. }
  455. ----
  456. .XML
  457. [source,xml,role="secondary"]
  458. ----
  459. <http>
  460. <!-- ... -->
  461. <headers>
  462. <xss-protection block="false"/>
  463. </headers>
  464. </http>
  465. ----
  466. .Kotlin
  467. [source,kotlin,role="secondary"]
  468. ----
  469. @EnableWebSecurity
  470. class SecurityConfig : WebSecurityConfigurerAdapter() {
  471. override fun configure(http: HttpSecurity) {
  472. // ...
  473. http {
  474. headers {
  475. xssProtection {
  476. block = false
  477. }
  478. }
  479. }
  480. }
  481. }
  482. ----
  483. ====
  484. [[servlet-headers-csp]]
  485. == Content Security Policy (CSP)
  486. Spring Security does not add xref:features/exploits/headers.adoc#headers-csp[Content Security Policy] by default, because a reasonable default is impossible to know without context of the application.
  487. The web application author must declare the security policy(s) to enforce and/or monitor for the protected resources.
  488. For example, given the following security policy:
  489. .Content Security Policy Example
  490. ====
  491. [source,http]
  492. ----
  493. Content-Security-Policy: script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/
  494. ----
  495. ====
  496. You can enable the CSP header as shown below:
  497. .Content Security Policy
  498. ====
  499. .Java
  500. [source,java,role="primary"]
  501. ----
  502. @EnableWebSecurity
  503. public class WebSecurityConfig extends
  504. WebSecurityConfigurerAdapter {
  505. @Override
  506. protected void configure(HttpSecurity http) {
  507. http
  508. // ...
  509. .headers(headers -> headers
  510. .contentSecurityPolicy(csp -> csp
  511. .policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
  512. )
  513. );
  514. }
  515. }
  516. ----
  517. .XML
  518. [source,xml,role="secondary"]
  519. ----
  520. <http>
  521. <!-- ... -->
  522. <headers>
  523. <content-security-policy
  524. policy-directives="script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/" />
  525. </headers>
  526. </http>
  527. ----
  528. .Kotlin
  529. [source,kotlin,role="secondary"]
  530. ----
  531. @EnableWebSecurity
  532. class SecurityConfig : WebSecurityConfigurerAdapter() {
  533. override fun configure(http: HttpSecurity) {
  534. http {
  535. // ...
  536. headers {
  537. contentSecurityPolicy {
  538. policyDirectives = "script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
  539. }
  540. }
  541. }
  542. }
  543. }
  544. ----
  545. ====
  546. To enable the CSP `report-only` header, provide the following configuration:
  547. .Content Security Policy Report Only
  548. ====
  549. .Java
  550. [source,java,role="primary"]
  551. ----
  552. @EnableWebSecurity
  553. public class WebSecurityConfig extends
  554. WebSecurityConfigurerAdapter {
  555. @Override
  556. protected void configure(HttpSecurity http) throws Exception {
  557. http
  558. // ...
  559. .headers(headers -> headers
  560. .contentSecurityPolicy(csp -> csp
  561. .policyDirectives("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/")
  562. .reportOnly()
  563. )
  564. );
  565. }
  566. }
  567. ----
  568. .XML
  569. [source,xml,role="secondary"]
  570. ----
  571. <http>
  572. <!-- ... -->
  573. <headers>
  574. <content-security-policy
  575. policy-directives="script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
  576. report-only="true" />
  577. </headers>
  578. </http>
  579. ----
  580. .Kotlin
  581. [source,kotlin,role="secondary"]
  582. ----
  583. @EnableWebSecurity
  584. class SecurityConfig : WebSecurityConfigurerAdapter() {
  585. override fun configure(http: HttpSecurity) {
  586. http {
  587. // ...
  588. headers {
  589. contentSecurityPolicy {
  590. policyDirectives = "script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/"
  591. reportOnly = true
  592. }
  593. }
  594. }
  595. }
  596. }
  597. ----
  598. ====
  599. [[servlet-headers-referrer]]
  600. == Referrer Policy
  601. Spring Security does not add xref:features/exploits/headers.adoc#headers-referrer[Referrer Policy] headers by default.
  602. You can enable the Referrer Policy header using the configuration as shown below:
  603. .Referrer Policy
  604. ====
  605. .Java
  606. [source,java,role="primary"]
  607. ----
  608. @EnableWebSecurity
  609. public class WebSecurityConfig extends
  610. WebSecurityConfigurerAdapter {
  611. @Override
  612. protected void configure(HttpSecurity http) {
  613. http
  614. // ...
  615. .headers(headers -> headers
  616. .referrerPolicy(referrer -> referrer
  617. .policy(ReferrerPolicy.SAME_ORIGIN)
  618. )
  619. );
  620. }
  621. }
  622. ----
  623. .XML
  624. [source,xml,role="secondary"]
  625. ----
  626. <http>
  627. <!-- ... -->
  628. <headers>
  629. <referrer-policy policy="same-origin" />
  630. </headers>
  631. </http>
  632. ----
  633. .Kotlin
  634. [source,kotlin,role="secondary"]
  635. ----
  636. @EnableWebSecurity
  637. class SecurityConfig : WebSecurityConfigurerAdapter() {
  638. override fun configure(http: HttpSecurity) {
  639. http {
  640. // ...
  641. headers {
  642. referrerPolicy {
  643. policy = ReferrerPolicy.SAME_ORIGIN
  644. }
  645. }
  646. }
  647. }
  648. }
  649. ----
  650. ====
  651. [[servlet-headers-feature]]
  652. == Feature Policy
  653. Spring Security does not add xref:features/exploits/headers.adoc#headers-feature[Feature Policy] headers by default.
  654. The following `Feature-Policy` header:
  655. .Feature-Policy Example
  656. ====
  657. [source]
  658. ----
  659. Feature-Policy: geolocation 'self'
  660. ----
  661. ====
  662. can enable the Feature Policy header using the configuration shown below:
  663. .Feature-Policy
  664. ====
  665. .Java
  666. [source,java,role="primary"]
  667. ----
  668. @EnableWebSecurity
  669. public class WebSecurityConfig extends
  670. WebSecurityConfigurerAdapter {
  671. @Override
  672. protected void configure(HttpSecurity http) throws Exception {
  673. http
  674. // ...
  675. .headers(headers -> headers
  676. .featurePolicy("geolocation 'self'")
  677. );
  678. }
  679. }
  680. ----
  681. .XML
  682. [source,xml,role="secondary"]
  683. ----
  684. <http>
  685. <!-- ... -->
  686. <headers>
  687. <feature-policy policy-directives="geolocation 'self'" />
  688. </headers>
  689. </http>
  690. ----
  691. .Kotlin
  692. [source,kotlin,role="secondary"]
  693. ----
  694. @EnableWebSecurity
  695. class SecurityConfig : WebSecurityConfigurerAdapter() {
  696. override fun configure(http: HttpSecurity) {
  697. http {
  698. // ...
  699. headers {
  700. featurePolicy("geolocation 'self'")
  701. }
  702. }
  703. }
  704. }
  705. ----
  706. ====
  707. [[servlet-headers-permissions]]
  708. == Permissions Policy
  709. Spring Security does not add xref:features/exploits/headers.adoc#headers-permissions[Permissions Policy] headers by default.
  710. The following `Permissions-Policy` header:
  711. .Permissions-Policy Example
  712. ====
  713. [source]
  714. ----
  715. Permissions-Policy: geolocation=(self)
  716. ----
  717. ====
  718. can enable the Permissions Policy header using the configuration shown below:
  719. .Permissions-Policy
  720. ====
  721. .Java
  722. [source,java,role="primary"]
  723. ----
  724. @EnableWebSecurity
  725. public class WebSecurityConfig extends
  726. WebSecurityConfigurerAdapter {
  727. @Override
  728. protected void configure(HttpSecurity http) throws Exception {
  729. http
  730. // ...
  731. .headers(headers -> headers
  732. .permissionsPolicy(permissions -> permissions
  733. .policy("geolocation=(self)")
  734. )
  735. );
  736. }
  737. }
  738. ----
  739. .XML
  740. [source,xml,role="secondary"]
  741. ----
  742. <http>
  743. <!-- ... -->
  744. <headers>
  745. <permissions-policy policy="geolocation=(self)" />
  746. </headers>
  747. </http>
  748. ----
  749. .Kotlin
  750. [source,kotlin,role="secondary"]
  751. ----
  752. @EnableWebSecurity
  753. class SecurityConfig : WebSecurityConfigurerAdapter() {
  754. override fun configure(http: HttpSecurity) {
  755. http {
  756. // ...
  757. headers {
  758. permissionPolicy {
  759. policy = "geolocation=(self)"
  760. }
  761. }
  762. }
  763. }
  764. }
  765. ----
  766. ====
  767. [[servlet-headers-clear-site-data]]
  768. == Clear Site Data
  769. Spring Security does not add xref:features/exploits/headers.adoc#headers-clear-site-data[Clear-Site-Data] headers by default.
  770. The following Clear-Site-Data header:
  771. .Clear-Site-Data Example
  772. ====
  773. ----
  774. Clear-Site-Data: "cache", "cookies"
  775. ----
  776. ====
  777. can be sent on log out with the following configuration:
  778. .Clear-Site-Data
  779. ====
  780. .Java
  781. [source,java,role="primary"]
  782. ----
  783. @EnableWebSecurity
  784. public class WebSecurityConfig extends
  785. WebSecurityConfigurerAdapter {
  786. @Override
  787. protected void configure(HttpSecurity http) throws Exception {
  788. http
  789. // ...
  790. .logout()
  791. .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(CACHE, COOKIES)));
  792. }
  793. }
  794. ----
  795. .Kotlin
  796. [source,kotlin,role="secondary"]
  797. ----
  798. @EnableWebSecurity
  799. class SecurityConfig : WebSecurityConfigurerAdapter() {
  800. override fun configure(http: HttpSecurity) {
  801. http {
  802. // ...
  803. logout {
  804. addLogoutHandler(HeaderWriterLogoutHandler(ClearSiteDataHeaderWriter(CACHE, COOKIES)))
  805. }
  806. }
  807. }
  808. }
  809. ----
  810. ====
  811. [[servlet-headers-custom]]
  812. == Custom Headers
  813. Spring Security has mechanisms to make it convenient to add the more common security headers to your application.
  814. However, it also provides hooks to enable adding custom headers.
  815. [[servlet-headers-static]]
  816. === Static Headers
  817. There may be times you wish to inject custom security headers into your application that are not supported out of the box.
  818. For example, given the following custom security header:
  819. [source]
  820. ----
  821. X-Custom-Security-Header: header-value
  822. ----
  823. The headers could be added to the response using the following Configuration:
  824. .StaticHeadersWriter
  825. ====
  826. .Java
  827. [source,java,role="primary"]
  828. ----
  829. @EnableWebSecurity
  830. public class WebSecurityConfig extends
  831. WebSecurityConfigurerAdapter {
  832. @Override
  833. protected void configure(HttpSecurity http) throws Exception {
  834. http
  835. // ...
  836. .headers(headers -> headers
  837. .addHeaderWriter(new StaticHeadersWriter("X-Custom-Security-Header","header-value"))
  838. );
  839. }
  840. }
  841. ----
  842. .XML
  843. [source,xml,role="secondary"]
  844. ----
  845. <http>
  846. <!-- ... -->
  847. <headers>
  848. <header name="X-Custom-Security-Header" value="header-value"/>
  849. </headers>
  850. </http>
  851. ----
  852. .Kotlin
  853. [source,kotlin,role="secondary"]
  854. ----
  855. @EnableWebSecurity
  856. class SecurityConfig : WebSecurityConfigurerAdapter() {
  857. override fun configure(http: HttpSecurity) {
  858. http {
  859. // ...
  860. headers {
  861. addHeaderWriter(StaticHeadersWriter("X-Custom-Security-Header","header-value"))
  862. }
  863. }
  864. }
  865. }
  866. ----
  867. ====
  868. [[servlet-headers-writer]]
  869. === Headers Writer
  870. When the namespace or Java configuration does not support the headers you want, you can create a custom `HeadersWriter` instance or even provide a custom implementation of the `HeadersWriter`.
  871. Let's take a look at an example of using an custom instance of `XFrameOptionsHeaderWriter`.
  872. If you wanted to explicitly configure <<servlet-headers-frame-options>> it could be done with the following Configuration:
  873. .Headers Writer
  874. ====
  875. .Java
  876. [source,java,role="primary"]
  877. ----
  878. @EnableWebSecurity
  879. public class WebSecurityConfig extends
  880. WebSecurityConfigurerAdapter {
  881. @Override
  882. protected void configure(HttpSecurity http) throws Exception {
  883. http
  884. // ...
  885. .headers(headers -> headers
  886. .addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
  887. );
  888. }
  889. }
  890. ----
  891. .XML
  892. [source,xml,role="secondary"]
  893. ----
  894. <http>
  895. <!-- ... -->
  896. <headers>
  897. <header ref="frameOptionsWriter"/>
  898. </headers>
  899. </http>
  900. <!-- Requires the c-namespace.
  901. See https://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-c-namespace
  902. -->
  903. <beans:bean id="frameOptionsWriter"
  904. class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"
  905. c:frameOptionsMode="SAMEORIGIN"/>
  906. ----
  907. .Kotlin
  908. [source,kotlin,role="secondary"]
  909. ----
  910. @EnableWebSecurity
  911. class SecurityConfig : WebSecurityConfigurerAdapter() {
  912. override fun configure(http: HttpSecurity) {
  913. http {
  914. // ...
  915. headers {
  916. addHeaderWriter(XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN))
  917. }
  918. }
  919. }
  920. }
  921. ----
  922. ====
  923. [[headers-delegatingrequestmatcherheaderwriter]]
  924. === DelegatingRequestMatcherHeaderWriter
  925. At times you may want to only write a header for certain requests.
  926. For example, perhaps you want to only protect your log in page from being framed.
  927. You could use the `DelegatingRequestMatcherHeaderWriter` to do so.
  928. An example of using `DelegatingRequestMatcherHeaderWriter` in Java Configuration can be seen below:
  929. .DelegatingRequestMatcherHeaderWriter Java Configuration
  930. ====
  931. .Java
  932. [source,java,role="primary"]
  933. ----
  934. @EnableWebSecurity
  935. public class WebSecurityConfig extends
  936. WebSecurityConfigurerAdapter {
  937. @Override
  938. protected void configure(HttpSecurity http) throws Exception {
  939. RequestMatcher matcher = new AntPathRequestMatcher("/login");
  940. DelegatingRequestMatcherHeaderWriter headerWriter =
  941. new DelegatingRequestMatcherHeaderWriter(matcher,new XFrameOptionsHeaderWriter());
  942. http
  943. // ...
  944. .headers(headers -> headers
  945. .frameOptions(frameOptions -> frameOptions.disable())
  946. .addHeaderWriter(headerWriter)
  947. );
  948. }
  949. }
  950. ----
  951. .XML
  952. [source,xml,role="secondary"]
  953. ----
  954. <http>
  955. <!-- ... -->
  956. <headers>
  957. <frame-options disabled="true"/>
  958. <header ref="headerWriter"/>
  959. </headers>
  960. </http>
  961. <beans:bean id="headerWriter"
  962. class="org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter">
  963. <beans:constructor-arg>
  964. <bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher"
  965. c:pattern="/login"/>
  966. </beans:constructor-arg>
  967. <beans:constructor-arg>
  968. <beans:bean
  969. class="org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter"/>
  970. </beans:constructor-arg>
  971. </beans:bean>
  972. ----
  973. .Kotlin
  974. [source,kotlin,role="secondary"]
  975. ----
  976. @EnableWebSecurity
  977. class SecurityConfig : WebSecurityConfigurerAdapter() {
  978. override fun configure(http: HttpSecurity) {
  979. val matcher: RequestMatcher = AntPathRequestMatcher("/login")
  980. val headerWriter = DelegatingRequestMatcherHeaderWriter(matcher, XFrameOptionsHeaderWriter())
  981. http {
  982. headers {
  983. frameOptions {
  984. disable()
  985. }
  986. addHeaderWriter(headerWriter)
  987. }
  988. }
  989. }
  990. }
  991. ----
  992. ====