diff --git a/config/src/test/groovy/org/springframework/security/config/http/HttpHeadersConfigTests.groovy b/config/src/test/groovy/org/springframework/security/config/http/HttpHeadersConfigTests.groovy deleted file mode 100644 index ca3c807cc7..0000000000 --- a/config/src/test/groovy/org/springframework/security/config/http/HttpHeadersConfigTests.groovy +++ /dev/null @@ -1,961 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package org.springframework.security.config.http - -import org.springframework.beans.factory.BeanCreationException -import org.springframework.beans.factory.parsing.BeanDefinitionParsingException -import org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException -import org.springframework.mock.web.MockFilterChain -import org.springframework.mock.web.MockHttpServletRequest -import org.springframework.mock.web.MockHttpServletResponse -import org.springframework.security.web.FilterChainProxy -import org.springframework.security.web.header.HeaderWriterFilter -import org.springframework.security.web.header.writers.StaticHeadersWriter -import org.springframework.security.web.util.matcher.AnyRequestMatcher - -/** - * - * @author Rob Winch - * @author Tim Ysewyn - */ -class HttpHeadersConfigTests extends AbstractHttpConfigTests { - def defaultHeaders = ['X-Content-Type-Options':'nosniff', - 'X-Frame-Options':'DENY', - 'Strict-Transport-Security': 'max-age=31536000 ; includeSubDomains', - 'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate', - 'Expires' : '0', - 'Pragma':'no-cache', - 'X-XSS-Protection' : '1; mode=block'] - def 'headers disabled'() { - setup: - httpAutoConfig { - 'headers'(disabled:true) - } - createAppContext() - - when: - def hf = getFilter(HeaderWriterFilter) - then: - !hf - } - - def 'headers disabled with child fails'() { - when: - httpAutoConfig { - 'headers'(disabled:true) { - 'content-type-options'() - } - } - createAppContext() - then: - thrown(BeanDefinitionParsingException) - } - - def 'default headers'() { - httpAutoConfig { - } - createAppContext() - - when: - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, defaultHeaders) - } - - def 'http headers with empty headers'() { - setup: - httpAutoConfig { - 'headers'() - } - createAppContext() - when: - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, defaultHeaders) - } - - def 'http headers frame-options@policy=SAMEORIGIN with defaults'() { - httpAutoConfig { - 'headers'() { - 'frame-options'(policy:'SAMEORIGIN') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - def expectedHeaders = [:] << defaultHeaders - expectedHeaders['X-Frame-Options'] = 'SAMEORIGIN' - - expect: - assertHeaders(response, expectedHeaders) - } - - - // --- defaults disabled - - // gh-3986 - def 'http headers defaults-disabled with no override'() { - httpAutoConfig { - 'headers'('defaults-disabled':true) { - } - } - createAppContext() - - expect: - getFilter(HeaderWriterFilter) == null - } - - def 'http headers content-type-options'() { - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'content-type-options'() - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - - expect: - assertHeaders(response, ['X-Content-Type-Options':'nosniff']) - } - - def 'http headers frame-options defaults to DENY'() { - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'frame-options'() - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - - expect: - assertHeaders(response, ['X-Frame-Options':'DENY']) - } - - def 'http headers frame-options DENY'() { - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'frame-options'(policy : 'DENY') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - - expect: - assertHeaders(response, ['X-Frame-Options':'DENY']) - } - - def 'http headers frame-options SAMEORIGIN'() { - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'frame-options'(policy : 'SAMEORIGIN') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - - expect: - assertHeaders(response, ['X-Frame-Options':'SAMEORIGIN']) - } - - def 'http headers frame-options ALLOW-FROM no origin reports error'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'frame-options'(policy : 'ALLOW-FROM', strategy : 'static') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - - then: - BeanDefinitionParsingException e = thrown() - e.message.contains "Strategy requires a 'value' to be set." // FIME better error message? - } - - def 'http headers frame-options ALLOW-FROM spaces only origin reports error'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'frame-options'(policy : 'ALLOW-FROM', strategy: 'static', value : ' ') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - - then: - BeanDefinitionParsingException e = thrown() - e.message.contains "Strategy requires a 'value' to be set." // FIME better error message? - } - - def 'http headers frame-options ALLOW-FROM'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'frame-options'(policy : 'ALLOW-FROM', strategy: 'static', value : 'https://example.com') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - - then: - assertHeaders(response, ['X-Frame-Options':'ALLOW-FROM https://example.com']) - } - - def 'http headers frame-options ALLOW-FROM with whitelist strategy'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'frame-options'(policy : 'ALLOW-FROM', strategy: 'whitelist', value : 'https://example.com') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - - def request = new MockHttpServletRequest("GET", "") - request.setParameter("from", "https://example.com"); - hf.doFilter(request, response, new MockFilterChain()) - - then: - assertHeaders(response, ['X-Frame-Options':'ALLOW-FROM https://example.com']) - } - - def 'http headers header a=b'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'header'(name : 'a', value: 'b') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - - then: - assertHeaders(response, ['a':'b']) - } - - def 'http headers header a=b and c=d'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'header'(name : 'a', value: 'b') - 'header'(name : 'c', value: 'd') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - - then: - assertHeaders(response , ['a':'b', 'c':'d']) - } - - def 'http headers with ref'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'header'(ref:'headerWriter') - } - } - xml.'b:bean'(id: 'headerWriter', 'class': StaticHeadersWriter.name) { - 'b:constructor-arg'(value:'abc') {} - 'b:constructor-arg'(value:'def') {} - } - createAppContext() - when: - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - then: - assertHeaders(response, ['abc':'def']) - } - - def 'http headers header no name produces error'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'header'(value: 'b') - } - } - createAppContext() - - then: - thrown(BeanCreationException) - } - - def 'http headers header no value produces error'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'header'(name: 'a') - } - } - createAppContext() - - then: - thrown(BeanCreationException) - } - - def 'http headers xss-protection defaults'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'xss-protection'() - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - - then: - assertHeaders(response, ['X-XSS-Protection':'1; mode=block']) - } - - def 'http headers xss-protection enabled=true'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'xss-protection'(enabled:'true') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - - then: - assertHeaders(response, ['X-XSS-Protection':'1; mode=block']) - } - - def 'http headers xss-protection enabled=false'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'xss-protection'(enabled:'false') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - - then: - assertHeaders(response, ['X-XSS-Protection':'0']) - } - - def 'http headers xss-protection enabled=false and block=true produces error'() { - when: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'xss-protection'(enabled:'false', block:'true') - } - } - createAppContext() - - def hf = getFilter(HeaderWriterFilter) - - then: - BeanCreationException e = thrown() - e.message.contains 'Cannot set block to true with enabled false' - } - - def 'http headers cache-control'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'cache-control'() - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - then: - assertHeaders(response, ['Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate', - 'Expires' : '0', - 'Pragma':'no-cache']) - } - - def 'http headers hsts'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hsts'() - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, ['Strict-Transport-Security': 'max-age=31536000 ; includeSubDomains']) - } - - def 'http headers hsts default only invokes on HttpServletRequest.isSecure = true'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hsts'() - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - then: - response.headerNames.empty - } - - def 'http headers hsts custom'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hsts'('max-age-seconds':'1','include-subdomains':false, 'request-matcher-ref' : 'matcher') - } - } - - xml.'b:bean'(id: 'matcher', 'class': AnyRequestMatcher.name) - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - then: - assertHeaders(response, ['Strict-Transport-Security': 'max-age=1']) - } - - def 'http headers hpkp no pins'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hpkp'() - } - } - when: - createAppContext() - then: - XmlBeanDefinitionStoreException expected = thrown() - expected.message.contains 'The content of element \'hpkp\' is not complete' - } - - def 'http headers hpkp no pin'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hpkp'() { - 'pins'() - } - } - } - when: - createAppContext() - then: - XmlBeanDefinitionStoreException expected = thrown() - expected.message.contains 'The content of element \'pins\' is not complete' - } - - def 'http headers hpkp'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hpkp'() { - 'pins'() { - 'pin'('algorithm':'sha256', 'd6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=') - } - } - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, ['Public-Key-Pins-Report-Only': 'max-age=5184000 ; pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="']) - } - - def 'http headers hpkp with default algorithm'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hpkp'() { - 'pins'() { - 'pin'('d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=') - } - } - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, ['Public-Key-Pins-Report-Only': 'max-age=5184000 ; pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="']) - } - - def 'http headers hpkp only invokes on HttpServletRequest.isSecure = true'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hpkp'() { - 'pins'() { - 'pin'('algorithm':'sha256', 'E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=') - } - } - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - then: - response.headerNames.empty - } - - def 'http headers hpkp with custom max age'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hpkp'('max-age-seconds':'604800') { - 'pins'() { - 'pin'('algorithm':'sha256', 'd6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=') - } - } - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, ['Public-Key-Pins-Report-Only': 'max-age=604800 ; pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="']) - } - - def 'http headers hpkp@reportOnly=false'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hpkp'('report-only':'false') { - 'pins'() { - 'pin'('algorithm':'sha256', 'E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=') - } - } - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure: true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, ['Public-Key-Pins': 'max-age=5184000 ; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="']) - } - - def 'http headers hpkp@includeSubDomains=true'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hpkp'('include-subdomains':'true') { - 'pins'() { - 'pin'('algorithm':'sha256', 'E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=') - } - } - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure: true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, ['Public-Key-Pins-Report-Only': 'max-age=5184000 ; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" ; includeSubDomains']) - } - - def 'http headers hpkp with report-uri'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'hpkp'('report-uri':'http://example.net/pkp-report') { - 'pins'() { - 'pin'('algorithm':'sha256', 'E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=') - } - } - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure: true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, ['Public-Key-Pins-Report-Only': 'max-age=5184000 ; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=" ; report-uri="http://example.net/pkp-report"']) - } - - // --- disable single default header --- - - def 'http headers cache-controls@disabled=true'() { - setup: - httpAutoConfig { - 'headers'() { - 'cache-control'(disabled:true) - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - def expectedHeaders = [:] << defaultHeaders - expectedHeaders.remove('Cache-Control') - expectedHeaders.remove('Expires') - expectedHeaders.remove('Pragma') - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, expectedHeaders) - } - - def 'http headers content-type-options@disabled=true'() { - setup: - httpAutoConfig { - 'headers'() { - 'content-type-options'(disabled:true) - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - def expectedHeaders = [:] << defaultHeaders - expectedHeaders.remove('X-Content-Type-Options') - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, expectedHeaders) - } - - def 'http headers hsts@disabled=true'() { - setup: - httpAutoConfig { - 'headers'() { - 'hsts'(disabled:true) - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - def expectedHeaders = [:] << defaultHeaders - expectedHeaders.remove('Strict-Transport-Security') - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - then: - assertHeaders(response, expectedHeaders) - } - - def 'http headers hpkp@disabled=true'() { - setup: - httpAutoConfig { - 'headers'() { - 'hpkp'(disabled:true) { - 'pins'() { - 'pin'('algorithm':'sha256', 'E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=') - } - } - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - def expectedHeaders = [:] << defaultHeaders - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, expectedHeaders) - } - - def 'http headers frame-options@disabled=true'() { - setup: - httpAutoConfig { - 'headers'() { - 'frame-options'(disabled:true) - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - def expectedHeaders = [:] << defaultHeaders - expectedHeaders.remove('X-Frame-Options') - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, expectedHeaders) - } - - def 'http headers xss-protection@disabled=true'() { - setup: - httpAutoConfig { - 'headers'() { - 'xss-protection'(disabled:true) - } - } - createAppContext() - def springSecurityFilterChain = appContext.getBean(FilterChainProxy) - MockHttpServletResponse response = new MockHttpServletResponse() - def expectedHeaders = [:] << defaultHeaders - expectedHeaders.remove('X-XSS-Protection') - when: - springSecurityFilterChain.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, expectedHeaders) - } - - // --- disable error handling --- - - def 'http headers hsts@disabled=true no include-subdomains'() { - setup: - httpAutoConfig { - 'headers'() { - 'hsts'(disabled:true,'include-subdomains':true) - } - } - when: - createAppContext() - then: - BeanDefinitionParsingException expected = thrown() - expected.message.contains 'include-subdomains' - } - - def 'http headers hsts@disabled=true no max-age'() { - setup: - httpAutoConfig { - 'headers'() { - 'hsts'(disabled:true,'max-age-seconds':123) - } - } - when: - createAppContext() - then: - BeanDefinitionParsingException expected = thrown() - expected.message.contains 'max-age' - } - - def 'http headers hsts@disabled=true no matcher-ref'() { - setup: - httpAutoConfig { - 'headers'() { - 'hsts'(disabled:true,'request-matcher-ref':'matcher') - } - } - xml.'b:bean'(id: 'matcher', 'class': AnyRequestMatcher.name) - when: - createAppContext() - then: - BeanDefinitionParsingException expected = thrown() - expected.message.contains 'request-matcher-ref' - } - - def 'http xss@disabled=true no enabled'() { - setup: - httpAutoConfig { - 'headers'() { - 'xss-protection'(disabled:true,'enabled':true) - } - } - when: - createAppContext() - then: - BeanDefinitionParsingException expected = thrown() - expected.message.contains 'enabled' - } - - def 'http xss@disabled=true no block'() { - setup: - httpAutoConfig { - 'headers'() { - 'xss-protection'(disabled:true,'block':true) - } - } - when: - createAppContext() - then: - BeanDefinitionParsingException expected = thrown() - expected.message.contains 'block' - } - - def 'http frame-options@disabled=true no policy'() { - setup: - httpAutoConfig { - 'headers'() { - 'frame-options'(disabled:true,'policy':'DENY') - } - } - when: - createAppContext() - then: - BeanDefinitionParsingException expected = thrown() - expected.message.contains 'policy' - } - - def 'http headers defaults : content-security-policy'() { - setup: - httpAutoConfig { - 'headers'() { - 'content-security-policy'('policy-directives':'default-src \'self\'') - } - } - createAppContext() - when: - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - def expectedHeaders = [:] << defaultHeaders - expectedHeaders['Content-Security-Policy'] = 'default-src \'self\'' - then: - assertHeaders(response, expectedHeaders) - } - - def 'http headers disabled : content-security-policy not included'() { - setup: - httpAutoConfig { - 'headers'(disabled:true) { - 'content-security-policy'('policy-directives':'default-src \'self\'') - } - } - createAppContext() - when: - def hf = getFilter(HeaderWriterFilter) - then: - !hf - } - - def 'http headers defaults disabled : content-security-policy only'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'content-security-policy'('policy-directives':'default-src \'self\'') - } - } - createAppContext() - when: - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - then: - assertHeaders(response, ['Content-Security-Policy':'default-src \'self\'']) - } - - def 'http headers defaults : content-security-policy with empty directives'() { - when: - httpAutoConfig { - 'headers'() { - 'content-security-policy'('policy-directives':'') - } - } - createAppContext() - then: - thrown(BeanDefinitionParsingException) - } - - def 'http headers defaults : content-security-policy report-only=true'() { - setup: - httpAutoConfig { - 'headers'() { - 'content-security-policy'('policy-directives':'default-src https:; report-uri https://example.com/', 'report-only':true) - } - } - createAppContext() - when: - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest(secure:true, method: "GET"), response, new MockFilterChain()) - def expectedHeaders = [:] << defaultHeaders - expectedHeaders['Content-Security-Policy-Report-Only'] = 'default-src https:; report-uri https://example.com/' - then: - assertHeaders(response, expectedHeaders) - } - - def 'http headers defaults : referrer-policy'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'referrer-policy'() - } - } - createAppContext() - when: - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - then: - assertHeaders(response, ['Referrer-Policy': 'no-referrer']) - } - - def 'http headers defaults : referrer-policy same-origin'() { - setup: - httpAutoConfig { - 'headers'('defaults-disabled':true) { - 'referrer-policy'('policy': 'same-origin') - } - } - createAppContext() - when: - def hf = getFilter(HeaderWriterFilter) - MockHttpServletResponse response = new MockHttpServletResponse() - hf.doFilter(new MockHttpServletRequest("GET", ""), response, new MockFilterChain()) - then: - assertHeaders(response, ['Referrer-Policy': 'same-origin']) - } - - def assertHeaders(MockHttpServletResponse response, Map expected) { - assert response.headerNames == expected.keySet() - expected.each { headerName, value -> - assert response.getHeaderValues(headerName) == [value] - } - } -} diff --git a/config/src/test/java/org/springframework/security/config/http/HttpHeadersConfigTests.java b/config/src/test/java/org/springframework/security/config/http/HttpHeadersConfigTests.java new file mode 100644 index 0000000000..6e34b5f5bc --- /dev/null +++ b/config/src/test/java/org/springframework/security/config/http/HttpHeadersConfigTests.java @@ -0,0 +1,776 @@ +/* + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.config.http; + +import com.google.common.collect.ImmutableMap; +import org.junit.Rule; +import org.junit.Test; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; +import org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException; +import org.springframework.security.config.test.SpringTestRule; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultMatcher; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * + * @author Rob Winch + * @author Tim Ysewyn + * @author Josh Cummings + */ +public class HttpHeadersConfigTests { + + private static final String CONFIG_LOCATION_PREFIX = + "classpath:org/springframework/security/config/http/HttpHeadersConfigTests"; + + static final Map defaultHeaders = + ImmutableMap.builder() + .put("X-Content-Type-Options", "nosniff") + .put("X-Frame-Options", "DENY") + .put("Strict-Transport-Security", "max-age=31536000 ; includeSubDomains") + .put("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate") + .put("Expires", "0") + .put("Pragma", "no-cache") + .put("X-XSS-Protection", "1; mode=block") + .build(); + + @Rule + public final SpringTestRule spring = new SpringTestRule(); + + @Autowired + MockMvc mvc; + + @Test + public void requestWhenHeadersDisabledThenResponseExcludesAllSecureHeaders() + throws Exception { + + this.spring.configLocations(this.xml("HeadersDisabled")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(excludesDefaults()); + } + + @Test + public void configureWhenHeadersDisabledHavingChildElementThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("HeadersDisabledHavingChildElement")).autowire()) + .isInstanceOf(BeanDefinitionParsingException.class) + .hasMessageContaining("Cannot specify with child elements"); + } + + @Test + public void requestWhenHeadersEnabledThenResponseContainsAllSecureHeaders() + throws Exception { + + this.spring.configLocations(this.xml("DefaultConfig")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includesDefaults()); + } + + @Test + public void requestWhenHeadersElementUsedThenResponseContainsAllSecureHeaders() + throws Exception { + + this.spring.configLocations(this.xml("HeadersEnabled")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includesDefaults()); + } + + @Test + public void requestWhenFrameOptionsConfiguredThenIncludesHeader() + throws Exception { + + Map headers = new HashMap(defaultHeaders); + headers.put("X-Frame-Options", "SAMEORIGIN"); + + this.spring.configLocations(this.xml("WithFrameOptions")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includes(headers)); + } + + // -- defaults disabled + + /** + * gh-3986 + */ + @Test + public void requestWhenDefaultsDisabledWithNoOverrideThenExcludesAllSecureHeaders() + throws Exception { + + this.spring.configLocations(this.xml("DefaultsDisabledWithNoOverride")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(excludesDefaults()); + } + + @Test + public void requestWhenUsingContentTypeOptionsThenDefaultsToNoSniff() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("X-Content-Type-Options"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithContentTypeOptions")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("X-Content-Type-Options", "nosniff")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void requestWhenUsingFrameOptionsThenDefaultsToDeny() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("X-Frame-Options"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithFrameOptions")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("X-Frame-Options", "DENY")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void requestWhenUsingFrameOptionsDenyThenRespondsWithDeny() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("X-Frame-Options"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithFrameOptionsDeny")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("X-Frame-Options", "DENY")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void requestWhenUsingFrameOptionsSameOriginThenRespondsWithSameOrigin() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("X-Frame-Options"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithFrameOptionsSameOrigin")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("X-Frame-Options", "SAMEORIGIN")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void configureWhenUsingFrameOptionsAllowFromNoOriginThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("DefaultsDisabledWithFrameOptionsAllowFromNoOrigin")).autowire()) + .isInstanceOf(BeanDefinitionParsingException.class) + .hasMessageContaining("Strategy requires a 'value' to be set."); // FIXME better error message? + } + + @Test + public void configureWhenUsingFrameOptionsAllowFromBlankOriginThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("DefaultsDisabledWithFrameOptionsAllowFromBlankOrigin")).autowire()) + .isInstanceOf(BeanDefinitionParsingException.class) + .hasMessageContaining("Strategy requires a 'value' to be set."); // FIXME better error message? + } + + @Test + public void requestWhenUsingFrameOptionsAllowFromThenRespondsWithAllowFrom() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("X-Frame-Options"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithFrameOptionsAllowFrom")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("X-Frame-Options", "ALLOW-FROM https://example.org")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void requestWhenUsingFrameOptionsAllowFromWhitelistThenRespondsWithAllowFrom() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("X-Frame-Options"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithFrameOptionsAllowFromWhitelist")).autowire(); + + this.mvc.perform(get("/").param("from", "https://example.org")) + .andExpect(status().isOk()) + .andExpect(header().string("X-Frame-Options", "ALLOW-FROM https://example.org")) + .andExpect(excludes(excludedHeaders)); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("X-Frame-Options", "DENY")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void requestWhenUsingCustomHeaderThenRespondsWithThatHeader() + throws Exception { + + this.spring.configLocations(this.xml("DefaultsDisabledWithCustomHeader")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("a", "b")) + .andExpect(header().string("c", "d")) + .andExpect(excludesDefaults()); + } + + @Test + public void requestWhenUsingCustomHeaderWriterThenRespondsWithThatHeader() + throws Exception { + + this.spring.configLocations(this.xml("DefaultsDisabledWithCustomHeaderWriter")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("abc", "def")) + .andExpect(excludesDefaults()); + } + + @Test + public void configureWhenUsingCustomHeaderNameOnlyThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("DefaultsDisabledWithOnlyHeaderName")).autowire()) + .isInstanceOf(BeanCreationException.class); + } + + @Test + public void configureWhenUsingCustomHeaderValueOnlyThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("DefaultsDisabledWithOnlyHeaderValue")).autowire()) + .isInstanceOf(BeanCreationException.class); + } + + @Test + public void requestWhenUsingXssProtectionThenDefaultsToModeBlock() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("X-XSS-Protection"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithXssProtection")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("X-XSS-Protection", "1; mode=block")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void requestWhenEnablingXssProtectionThenDefaultsToModeBlock() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("X-XSS-Protection"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithXssProtectionEnabled")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("X-XSS-Protection", "1; mode=block")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void requestWhenDisablingXssProtectionThenDefaultsToZero() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("X-XSS-Protection"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithXssProtectionDisabled")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("X-XSS-Protection", "0")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void configureWhenXssProtectionDisabledAndBlockSetThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("DefaultsDisabledWithXssProtectionDisabledAndBlockSet")).autowire()) + .isInstanceOf(BeanCreationException.class) + .hasMessageContaining("Cannot set block to true with enabled false"); + } + + @Test + public void requestWhenUsingCacheControlThenRespondsWithCorrespondingHeaders() + throws Exception { + + Map includedHeaders = ImmutableMap.builder() + .put("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate") + .put("Expires", "0") + .put("Pragma", "no-cache") + .build(); + + this.spring.configLocations(this.xml("DefaultsDisabledWithCacheControl")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(includes(includedHeaders)); + } + + @Test + public void requestWhenUsingHstsThenRespondsWithHstsHeader() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("Strict-Transport-Security"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithHsts")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(header().string("Strict-Transport-Security", "max-age=31536000 ; includeSubDomains")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void insecureRequestWhenUsingHstsThenExcludesHstsHeader() + throws Exception { + + this.spring.configLocations(this.xml("DefaultsDisabledWithHsts")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(excludesDefaults()); + } + + @Test + public void insecureRequestWhenUsingCustomHstsRequestMatcherThenIncludesHstsHeader() + throws Exception { + + Set excludedHeaders = new HashSet<>(defaultHeaders.keySet()); + excludedHeaders.remove("Strict-Transport-Security"); + + this.spring.configLocations(this.xml("DefaultsDisabledWithCustomHstsRequestMatcher")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().string("Strict-Transport-Security", "max-age=1")) + .andExpect(excludes(excludedHeaders)); + } + + @Test + public void configureWhenUsingHpkpWithoutPinsThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("DefaultsDisabledWithEmptyHpkp")).autowire()) + .isInstanceOf(XmlBeanDefinitionStoreException.class) + .hasMessageContaining("The content of element 'hpkp' is not complete"); + } + + @Test + public void configureWhenUsingHpkpWithEmptyPinsThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("DefaultsDisabledWithEmptyPins")).autowire()) + .isInstanceOf(XmlBeanDefinitionStoreException.class) + .hasMessageContaining("The content of element 'pins' is not complete"); + } + + @Test + public void requestWhenUsingHpkpThenIncludesHpkpHeader() + throws Exception { + this.spring.configLocations(this.xml("DefaultsDisabledWithHpkp")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(header().string( + "Public-Key-Pins-Report-Only", + "max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\"")) + .andExpect(excludesDefaults()); + } + + @Test + public void requestWhenUsingHpkpDefaultsThenIncludesHpkpHeaderUsingSha256() + throws Exception { + this.spring.configLocations(this.xml("DefaultsDisabledWithHpkpDefaults")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(header().string( + "Public-Key-Pins-Report-Only", + "max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\"")) + .andExpect(excludesDefaults()); + } + + @Test + public void insecureRequestWhenUsingHpkpThenExcludesHpkpHeader() + throws Exception { + this.spring.configLocations(this.xml("DefaultsDisabledWithHpkpDefaults")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(header().doesNotExist("Public-Key-Pins-Report-Only")) + .andExpect(excludesDefaults()); + } + + @Test + public void requestWhenUsingHpkpCustomMaxAgeThenIncludesHpkpHeaderAccordingly() + throws Exception { + this.spring.configLocations(this.xml("DefaultsDisabledWithHpkpMaxAge")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(header().string( + "Public-Key-Pins-Report-Only", + "max-age=604800 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\"")) + .andExpect(excludesDefaults()); + } + + @Test + public void requestWhenUsingHpkpReportThenIncludesHpkpHeaderAccordingly() + throws Exception { + this.spring.configLocations(this.xml("DefaultsDisabledWithHpkpReport")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(header().string( + "Public-Key-Pins", + "max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\"")) + .andExpect(excludesDefaults()); + } + + @Test + public void requestWhenUsingHpkpIncludeSubdomainsThenIncludesHpkpHeaderAccordingly() + throws Exception { + this.spring.configLocations(this.xml("DefaultsDisabledWithHpkpIncludeSubdomains")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(header().string( + "Public-Key-Pins-Report-Only", + "max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; includeSubDomains")) + .andExpect(excludesDefaults()); + } + + @Test + public void requestWhenUsingHpkpReportUriThenIncludesHpkpHeaderAccordingly() + throws Exception { + this.spring.configLocations(this.xml("DefaultsDisabledWithHpkpReportUri")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(header().string( + "Public-Key-Pins-Report-Only", + "max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; report-uri=\"http://example.net/pkp-report\"")) + .andExpect(excludesDefaults()); + } + + // -- single-header disabled + + @Test + public void requestWhenCacheControlDisabledThenExcludesHeader() + throws Exception { + + Collection cacheControl = Arrays.asList("Cache-Control", "Expires", "Pragma"); + Map allButCacheControl = remove(defaultHeaders, cacheControl); + + this.spring.configLocations(this.xml("CacheControlDisabled")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includes(allButCacheControl)) + .andExpect(excludes(cacheControl)); + } + + @Test + public void requestWhenContentTypeOptionsDisabledThenExcludesHeader() + throws Exception { + + Collection contentTypeOptions = Arrays.asList("X-Content-Type-Options"); + Map allButContentTypeOptions = remove(defaultHeaders, contentTypeOptions); + + this.spring.configLocations(this.xml("ContentTypeOptionsDisabled")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includes(allButContentTypeOptions)) + .andExpect(excludes(contentTypeOptions)); + } + + @Test + public void requestWhenHstsDisabledThenExcludesHeader() + throws Exception { + + Collection hsts = Arrays.asList("Strict-Transport-Security"); + Map allButHsts = remove(defaultHeaders, hsts); + + this.spring.configLocations(this.xml("HstsDisabled")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includes(allButHsts)) + .andExpect(excludes(hsts)); + } + + @Test + public void requestWhenHpkpDisabledThenExcludesHeader() + throws Exception { + + this.spring.configLocations(this.xml("HpkpDisabled")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includesDefaults()); + } + + @Test + public void requestWhenFrameOptionsDisabledThenExcludesHeader() + throws Exception { + + Collection frameOptions = Arrays.asList("X-Frame-Options"); + Map allButFrameOptions = remove(defaultHeaders, frameOptions); + + this.spring.configLocations(this.xml("FrameOptionsDisabled")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includes(allButFrameOptions)) + .andExpect(excludes(frameOptions)); + } + + @Test + public void requestWhenXssProtectionDisabledThenExcludesHeader() + throws Exception { + + Collection xssProtection = Arrays.asList("X-XSS-Protection"); + Map allButXssProtection = remove(defaultHeaders, xssProtection); + + this.spring.configLocations(this.xml("XssProtectionDisabled")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includes(allButXssProtection)) + .andExpect(excludes(xssProtection)); + } + + // --- disable error handling --- + + @Test + public void configureWhenHstsDisabledAndIncludeSubdomainsSpecifiedThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("HstsDisabledSpecifyingIncludeSubdomains")).autowire()) + .isInstanceOf(BeanDefinitionParsingException.class) + .hasMessageContaining("include-subdomains"); + } + + @Test + public void configureWhenHstsDisabledAndMaxAgeSpecifiedThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("HstsDisabledSpecifyingMaxAge")).autowire()) + .isInstanceOf(BeanDefinitionParsingException.class) + .hasMessageContaining("max-age"); + } + + @Test + public void configureWhenHstsDisabledAndRequestMatcherSpecifiedThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("HstsDisabledSpecifyingRequestMatcher")).autowire()) + .isInstanceOf(BeanDefinitionParsingException.class) + .hasMessageContaining("request-matcher-ref"); + } + + @Test + public void configureWhenXssProtectionDisabledAndEnabledThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("XssProtectionDisabledAndEnabled")).autowire()) + .isInstanceOf(BeanDefinitionParsingException.class) + .hasMessageContaining("enabled"); + } + + @Test + public void configureWhenXssProtectionDisabledAndBlockSpecifiedThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("XssProtectionDisabledSpecifyingBlock")).autowire()) + .isInstanceOf(BeanDefinitionParsingException.class) + .hasMessageContaining("block"); + } + + @Test + public void configureWhenFrameOptionsDisabledAndPolicySpecifiedThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("FrameOptionsDisabledSpecifyingPolicy")).autowire()) + .isInstanceOf(BeanDefinitionParsingException.class) + .hasMessageContaining("policy"); + } + + @Test + public void requestWhenContentSecurityPolicyDirectivesConfiguredThenIncludesDirectives() + throws Exception { + + Map includedHeaders = new HashMap<>(defaultHeaders); + includedHeaders.put("Content-Security-Policy", "default-src 'self'"); + + this.spring.configLocations(this.xml("ContentSecurityPolicyWithPolicyDirectives")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includes(includedHeaders)); + } + + @Test + public void requestWhenHeadersDisabledAndContentSecurityPolicyConfiguredThenExcludesHeader() + throws Exception { + + this.spring.configLocations(this.xml("HeadersDisabledWithContentSecurityPolicy")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(excludesDefaults()) + .andExpect(excludes("Content-Security-Policy")); + } + + @Test + public void requestWhenDefaultsDisabledAndContentSecurityPolicyConfiguredThenIncludesHeader() + throws Exception { + + this.spring.configLocations(this.xml("DefaultsDisabledWithContentSecurityPolicy")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(excludesDefaults()) + .andExpect(header().string("Content-Security-Policy", "default-src 'self'")); + } + + @Test + public void configureWhenContentSecurityPolicyConfiguredWithEmptyDirectivesThenAutowireFails() { + assertThatThrownBy(() -> + this.spring.configLocations(this.xml("ContentSecurityPolicyWithEmptyDirectives")).autowire()) + .isInstanceOf(BeanDefinitionParsingException.class); + } + + @Test + public void requestWhenContentSecurityPolicyConfiguredWithReportOnlyThenIncludesReportOnlyHeader() + throws Exception { + + Map includedHeaders = new HashMap<>(defaultHeaders); + includedHeaders.put("Content-Security-Policy-Report-Only", "default-src https:; report-uri https://example.org/"); + + this.spring.configLocations(this.xml("ContentSecurityPolicyWithReportOnly")).autowire(); + + this.mvc.perform(get("/").secure(true)) + .andExpect(status().isOk()) + .andExpect(includes(includedHeaders)); + } + + @Test + public void requestWhenReferrerPolicyConfiguredThenResponseDefaultsToNoReferrer() + throws Exception { + + this.spring.configLocations(this.xml("DefaultsDisabledWithReferrerPolicy")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(excludesDefaults()) + .andExpect(header().string("Referrer-Policy", "no-referrer")); + } + + @Test + public void requestWhenReferrerPolicyConfiguredWithSameOriginThenRespondsWithSameOrigin() + throws Exception { + + this.spring.configLocations(this.xml("DefaultsDisabledWithReferrerPolicySameOrigin")).autowire(); + + this.mvc.perform(get("/")) + .andExpect(status().isOk()) + .andExpect(excludesDefaults()) + .andExpect(header().string("Referrer-Policy", "same-origin")); + } + + @RestController + public static class SimpleController { + @GetMapping("/") + public String ok() { return "ok"; } + } + + private static ResultMatcher includesDefaults() { + return includes(defaultHeaders); + } + + private static ResultMatcher includes(Map headers) { + return result -> { + for ( Map.Entry header : headers.entrySet() ) { + header().string(header.getKey(), header.getValue()).match(result); + } + }; + } + + private static ResultMatcher excludesDefaults() { + return excludes(defaultHeaders.keySet()); + } + + private static ResultMatcher excludes(Collection headers) { + return result -> { + for ( String name : headers ) { + header().doesNotExist(name).match(result); + } + }; + } + + private static ResultMatcher excludes(String... headers) { + return excludes(Arrays.asList(headers)); + } + + private static Map remove(Map map, Collection keys) { + Map copy = new HashMap<>(map); + + for ( K key : keys ) { + copy.remove(key); + } + + return copy; + } + + private String xml(String configName) { + return CONFIG_LOCATION_PREFIX + "-" + configName + ".xml"; + } +} diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-CacheControlDisabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-CacheControlDisabled.xml new file mode 100644 index 0000000000..8cc3f97354 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-CacheControlDisabled.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentSecurityPolicyWithEmptyDirectives.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentSecurityPolicyWithEmptyDirectives.xml new file mode 100644 index 0000000000..b6c64a228b --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentSecurityPolicyWithEmptyDirectives.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentSecurityPolicyWithPolicyDirectives.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentSecurityPolicyWithPolicyDirectives.xml new file mode 100644 index 0000000000..ff3eee270a --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentSecurityPolicyWithPolicyDirectives.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentSecurityPolicyWithReportOnly.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentSecurityPolicyWithReportOnly.xml new file mode 100644 index 0000000000..55ae7559b8 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentSecurityPolicyWithReportOnly.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentTypeOptionsDisabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentTypeOptionsDisabled.xml new file mode 100644 index 0000000000..6e2d415bf6 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-ContentTypeOptionsDisabled.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultConfig.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultConfig.xml new file mode 100644 index 0000000000..2cacad9a18 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultConfig.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCacheControl.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCacheControl.xml new file mode 100644 index 0000000000..1692f68fa0 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCacheControl.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithContentSecurityPolicy.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithContentSecurityPolicy.xml new file mode 100644 index 0000000000..bcc2a6632c --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithContentSecurityPolicy.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithContentTypeOptions.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithContentTypeOptions.xml new file mode 100644 index 0000000000..ee6f20a0a1 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithContentTypeOptions.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCustomHeader.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCustomHeader.xml new file mode 100644 index 0000000000..31c6f8d305 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCustomHeader.xml @@ -0,0 +1,37 @@ + + + + + + + +
+
+ + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCustomHeaderWriter.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCustomHeaderWriter.xml new file mode 100644 index 0000000000..1991d74152 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCustomHeaderWriter.xml @@ -0,0 +1,41 @@ + + + + + + + +
+ + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCustomHstsRequestMatcher.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCustomHstsRequestMatcher.xml new file mode 100644 index 0000000000..8fa625c8aa --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithCustomHstsRequestMatcher.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithEmptyHpkp.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithEmptyHpkp.xml new file mode 100644 index 0000000000..6249be2c17 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithEmptyHpkp.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithEmptyPins.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithEmptyPins.xml new file mode 100644 index 0000000000..a37f9e7221 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithEmptyPins.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptions.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptions.xml new file mode 100644 index 0000000000..9fc1c78663 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptions.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFrom.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFrom.xml new file mode 100644 index 0000000000..481c0bc379 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFrom.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFromBlankOrigin.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFromBlankOrigin.xml new file mode 100644 index 0000000000..3be6ee362e --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFromBlankOrigin.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFromNoOrigin.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFromNoOrigin.xml new file mode 100644 index 0000000000..47fd581890 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFromNoOrigin.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFromWhitelist.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFromWhitelist.xml new file mode 100644 index 0000000000..8678f8cb84 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsAllowFromWhitelist.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsDeny.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsDeny.xml new file mode 100644 index 0000000000..3bd66acb25 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsDeny.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsSameOrigin.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsSameOrigin.xml new file mode 100644 index 0000000000..dfac109f13 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithFrameOptionsSameOrigin.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkp.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkp.xml new file mode 100644 index 0000000000..b6875c77e3 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkp.xml @@ -0,0 +1,40 @@ + + + + + + + + + + d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM= + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpDefaults.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpDefaults.xml new file mode 100644 index 0000000000..8c5b07c97b --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpDefaults.xml @@ -0,0 +1,40 @@ + + + + + + + + + + d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM= + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpIncludeSubdomains.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpIncludeSubdomains.xml new file mode 100644 index 0000000000..f9a911fa12 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpIncludeSubdomains.xml @@ -0,0 +1,40 @@ + + + + + + + + + + d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM= + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpMaxAge.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpMaxAge.xml new file mode 100644 index 0000000000..d1ee8f8ea0 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpMaxAge.xml @@ -0,0 +1,40 @@ + + + + + + + + + + d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM= + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpReport.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpReport.xml new file mode 100644 index 0000000000..e5d37074e7 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpReport.xml @@ -0,0 +1,40 @@ + + + + + + + + + + d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM= + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpReportUri.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpReportUri.xml new file mode 100644 index 0000000000..3fa18da5a6 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHpkpReportUri.xml @@ -0,0 +1,40 @@ + + + + + + + + + + d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM= + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHsts.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHsts.xml new file mode 100644 index 0000000000..6e1cebc789 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithHsts.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithNoOverride.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithNoOverride.xml new file mode 100644 index 0000000000..f7619328d4 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithNoOverride.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithOnlyHeaderName.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithOnlyHeaderName.xml new file mode 100644 index 0000000000..7978bd08c3 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithOnlyHeaderName.xml @@ -0,0 +1,36 @@ + + + + + + + +
+ + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithOnlyHeaderValue.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithOnlyHeaderValue.xml new file mode 100644 index 0000000000..fba21c98de --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithOnlyHeaderValue.xml @@ -0,0 +1,36 @@ + + + + + + + +
+ + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithReferrerPolicy.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithReferrerPolicy.xml new file mode 100644 index 0000000000..b9f6b38600 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithReferrerPolicy.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithReferrerPolicySameOrigin.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithReferrerPolicySameOrigin.xml new file mode 100644 index 0000000000..a7b319576d --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithReferrerPolicySameOrigin.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtection.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtection.xml new file mode 100644 index 0000000000..dfabc86980 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtection.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtectionDisabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtectionDisabled.xml new file mode 100644 index 0000000000..50c01fe7d3 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtectionDisabled.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtectionDisabledAndBlockSet.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtectionDisabledAndBlockSet.xml new file mode 100644 index 0000000000..b648cde25a --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtectionDisabledAndBlockSet.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtectionEnabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtectionEnabled.xml new file mode 100644 index 0000000000..cfa732f97b --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-DefaultsDisabledWithXssProtectionEnabled.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-FrameOptionsDisabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-FrameOptionsDisabled.xml new file mode 100644 index 0000000000..6ab1b5fa06 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-FrameOptionsDisabled.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-FrameOptionsDisabledSpecifyingPolicy.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-FrameOptionsDisabledSpecifyingPolicy.xml new file mode 100644 index 0000000000..73e94a3c87 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-FrameOptionsDisabledSpecifyingPolicy.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersDisabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersDisabled.xml new file mode 100644 index 0000000000..802f31eaff --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersDisabled.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersDisabledHavingChildElement.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersDisabledHavingChildElement.xml new file mode 100644 index 0000000000..4946f505e9 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersDisabledHavingChildElement.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersDisabledWithContentSecurityPolicy.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersDisabledWithContentSecurityPolicy.xml new file mode 100644 index 0000000000..64b7287c04 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersDisabledWithContentSecurityPolicy.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersEnabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersEnabled.xml new file mode 100644 index 0000000000..fab128bd32 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HeadersEnabled.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HpkpDisabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HpkpDisabled.xml new file mode 100644 index 0000000000..1b13db83d6 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HpkpDisabled.xml @@ -0,0 +1,40 @@ + + + + + + + + + + d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM= + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabled.xml new file mode 100644 index 0000000000..6bc89f24ca --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabled.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabledSpecifyingIncludeSubdomains.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabledSpecifyingIncludeSubdomains.xml new file mode 100644 index 0000000000..4fa83aa5d9 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabledSpecifyingIncludeSubdomains.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabledSpecifyingMaxAge.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabledSpecifyingMaxAge.xml new file mode 100644 index 0000000000..b23dd301a4 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabledSpecifyingMaxAge.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabledSpecifyingRequestMatcher.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabledSpecifyingRequestMatcher.xml new file mode 100644 index 0000000000..903f96c137 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-HstsDisabledSpecifyingRequestMatcher.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-WithFrameOptions.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-WithFrameOptions.xml new file mode 100644 index 0000000000..cbee408f6f --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-WithFrameOptions.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-XssProtectionDisabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-XssProtectionDisabled.xml new file mode 100644 index 0000000000..5b2ac369f2 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-XssProtectionDisabled.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-XssProtectionDisabledAndEnabled.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-XssProtectionDisabledAndEnabled.xml new file mode 100644 index 0000000000..c590b69dea --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-XssProtectionDisabledAndEnabled.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-XssProtectionDisabledSpecifyingBlock.xml b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-XssProtectionDisabledSpecifyingBlock.xml new file mode 100644 index 0000000000..c183c36d95 --- /dev/null +++ b/config/src/test/resources/org/springframework/security/config/http/HttpHeadersConfigTests-XssProtectionDisabledSpecifyingBlock.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + +