From 93d6a38ffd0c751ce7300e88a9f7a11a5d2fb4ae Mon Sep 17 00:00:00 2001 From: Ankur Pathak Date: Wed, 6 Feb 2019 14:04:35 +0530 Subject: [PATCH] Consider having HeaderWriters check before writing All HeadersWriter only write Header if its not already written. Fixes: gh-6454 gh-5193 --- .../ContentSecurityPolicyHeaderWriter.java | 8 ++++-- .../writers/FeaturePolicyHeaderWriter.java | 7 ++++-- .../web/header/writers/HpkpHeaderWriter.java | 8 ++++-- .../web/header/writers/HstsHeaderWriter.java | 7 ++++-- .../writers/ReferrerPolicyHeaderWriter.java | 7 ++++-- .../header/writers/StaticHeadersWriter.java | 11 +++++--- .../writers/XXssProtectionHeaderWriter.java | 7 ++++-- .../XFrameOptionsHeaderWriter.java | 13 +++++++--- ...ontentSecurityPolicyHeaderWriterTests.java | 25 +++++++++++++++++-- .../FeaturePolicyHeaderWriterTests.java | 13 +++++++++- .../header/writers/HpkpHeaderWriterTests.java | 25 ++++++++++++++++++- .../header/writers/HstsHeaderWriterTests.java | 14 +++++++++-- .../ReferrerPolicyHeaderWriterTests.java | 14 +++++++++-- .../writers/StaticHeaderWriterTests.java | 23 +++++++++++++++-- .../XXssProtectionHeaderWriterTests.java | 13 +++++++++- .../XFrameOptionsHeaderWriterTests.java | 15 ++++++++++- 16 files changed, 178 insertions(+), 32 deletions(-) diff --git a/web/src/main/java/org/springframework/security/web/header/writers/ContentSecurityPolicyHeaderWriter.java b/web/src/main/java/org/springframework/security/web/header/writers/ContentSecurityPolicyHeaderWriter.java index 82d348d890..c265d965ba 100644 --- a/web/src/main/java/org/springframework/security/web/header/writers/ContentSecurityPolicyHeaderWriter.java +++ b/web/src/main/java/org/springframework/security/web/header/writers/ContentSecurityPolicyHeaderWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -73,6 +73,7 @@ import javax.servlet.http.HttpServletResponse; *

* * @author Joe Grandja + * @author Ankur Pathak * @since 4.1 */ public final class ContentSecurityPolicyHeaderWriter implements HeaderWriter { @@ -100,7 +101,10 @@ public final class ContentSecurityPolicyHeaderWriter implements HeaderWriter { */ @Override public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { - response.setHeader((!reportOnly ? CONTENT_SECURITY_POLICY_HEADER : CONTENT_SECURITY_POLICY_REPORT_ONLY_HEADER), policyDirectives); + String headerName = !reportOnly ? CONTENT_SECURITY_POLICY_HEADER : CONTENT_SECURITY_POLICY_REPORT_ONLY_HEADER; + if (!response.containsHeader(headerName)) { + response.setHeader(headerName, policyDirectives); + } } /** diff --git a/web/src/main/java/org/springframework/security/web/header/writers/FeaturePolicyHeaderWriter.java b/web/src/main/java/org/springframework/security/web/header/writers/FeaturePolicyHeaderWriter.java index 1c5528b897..eb30402094 100644 --- a/web/src/main/java/org/springframework/security/web/header/writers/FeaturePolicyHeaderWriter.java +++ b/web/src/main/java/org/springframework/security/web/header/writers/FeaturePolicyHeaderWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -33,6 +33,7 @@ import org.springframework.util.Assert; * responsible for declaring the restrictions for a particular feature type. * * @author Vedran Pavic + * @author Ankur Pathak * @since 5.1 */ public final class FeaturePolicyHeaderWriter implements HeaderWriter { @@ -54,7 +55,9 @@ public final class FeaturePolicyHeaderWriter implements HeaderWriter { @Override public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { - response.setHeader(FEATURE_POLICY_HEADER, this.policyDirectives); + if (!response.containsHeader(FEATURE_POLICY_HEADER)) { + response.setHeader(FEATURE_POLICY_HEADER, this.policyDirectives); + } } /** diff --git a/web/src/main/java/org/springframework/security/web/header/writers/HpkpHeaderWriter.java b/web/src/main/java/org/springframework/security/web/header/writers/HpkpHeaderWriter.java index b0ad6897f8..989f695a50 100644 --- a/web/src/main/java/org/springframework/security/web/header/writers/HpkpHeaderWriter.java +++ b/web/src/main/java/org/springframework/security/web/header/writers/HpkpHeaderWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -100,6 +100,7 @@ import java.util.Map; *

* * @author Tim Ysewyn + * @author Ankur Pathak * @since 4.1 */ public final class HpkpHeaderWriter implements HeaderWriter { @@ -174,7 +175,10 @@ public final class HpkpHeaderWriter implements HeaderWriter { public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { if (requestMatcher.matches(request)) { if (!pins.isEmpty()) { - response.setHeader(reportOnly ? HPKP_RO_HEADER_NAME : HPKP_HEADER_NAME, hpkpHeaderValue); + String headerName = reportOnly ? HPKP_RO_HEADER_NAME : HPKP_HEADER_NAME; + if (!response.containsHeader(headerName)) { + response.setHeader(headerName, hpkpHeaderValue); + } } if (logger.isDebugEnabled()) { logger.debug("Not injecting HPKP header since there aren't any pins"); } diff --git a/web/src/main/java/org/springframework/security/web/header/writers/HstsHeaderWriter.java b/web/src/main/java/org/springframework/security/web/header/writers/HstsHeaderWriter.java index 2d4a015932..9593c4c53d 100644 --- a/web/src/main/java/org/springframework/security/web/header/writers/HstsHeaderWriter.java +++ b/web/src/main/java/org/springframework/security/web/header/writers/HstsHeaderWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2019 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. @@ -53,6 +53,7 @@ import org.springframework.util.Assert; *

* * @author Rob Winch + * @author Ankur Pathak * @since 3.2 */ public final class HstsHeaderWriter implements HeaderWriter { @@ -159,7 +160,9 @@ public final class HstsHeaderWriter implements HeaderWriter { */ public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { if (this.requestMatcher.matches(request)) { - response.setHeader(HSTS_HEADER_NAME, this.hstsHeaderValue); + if (!response.containsHeader(HSTS_HEADER_NAME)) { + response.setHeader(HSTS_HEADER_NAME, this.hstsHeaderValue); + } } else if (this.logger.isDebugEnabled()) { this.logger diff --git a/web/src/main/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriter.java b/web/src/main/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriter.java index 52df0c3136..a044a3699f 100644 --- a/web/src/main/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriter.java +++ b/web/src/main/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -49,6 +49,7 @@ import org.springframework.util.Assert; * * @author Eddú Meléndez * @author Kazuki Shimizu + * @author Ankur Pathak * @since 4.2 */ public class ReferrerPolicyHeaderWriter implements HeaderWriter { @@ -89,7 +90,9 @@ public class ReferrerPolicyHeaderWriter implements HeaderWriter { */ @Override public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { - response.setHeader(REFERRER_POLICY_HEADER, this.policy.getPolicy()); + if (!response.containsHeader(REFERRER_POLICY_HEADER)) { + response.setHeader(REFERRER_POLICY_HEADER, this.policy.getPolicy()); + } } public enum ReferrerPolicy { diff --git a/web/src/main/java/org/springframework/security/web/header/writers/StaticHeadersWriter.java b/web/src/main/java/org/springframework/security/web/header/writers/StaticHeadersWriter.java index bbd0665e7d..87823ee080 100644 --- a/web/src/main/java/org/springframework/security/web/header/writers/StaticHeadersWriter.java +++ b/web/src/main/java/org/springframework/security/web/header/writers/StaticHeadersWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -30,6 +30,7 @@ import org.springframework.util.Assert; * * @author Marten Deinum * @author Rob Winch + * @author Ankur Pathak * @since 3.2 */ public class StaticHeadersWriter implements HeaderWriter { @@ -56,8 +57,10 @@ public class StaticHeadersWriter implements HeaderWriter { public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { for (Header header : headers) { - for (String value : header.getValues()) { - response.addHeader(header.getName(), value); + if (!response.containsHeader(header.getName())) { + for (String value : header.getValues()) { + response.addHeader(header.getName(), value); + } } } } @@ -66,4 +69,4 @@ public class StaticHeadersWriter implements HeaderWriter { public String toString() { return getClass().getName() + " [headers=" + headers + "]"; } -} \ No newline at end of file +} diff --git a/web/src/main/java/org/springframework/security/web/header/writers/XXssProtectionHeaderWriter.java b/web/src/main/java/org/springframework/security/web/header/writers/XXssProtectionHeaderWriter.java index 1ed6d44329..6490045fe2 100644 --- a/web/src/main/java/org/springframework/security/web/header/writers/XXssProtectionHeaderWriter.java +++ b/web/src/main/java/org/springframework/security/web/header/writers/XXssProtectionHeaderWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2019 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. @@ -26,6 +26,7 @@ import org.springframework.security.web.header.HeaderWriter; * >X-XSS-Protection header. * * @author Rob Winch + * @author Ankur Pathak * @since 3.2 */ public final class XXssProtectionHeaderWriter implements HeaderWriter { @@ -47,7 +48,9 @@ public final class XXssProtectionHeaderWriter implements HeaderWriter { } public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { - response.setHeader(XSS_PROTECTION_HEADER, headerValue); + if (!response.containsHeader(XSS_PROTECTION_HEADER)) { + response.setHeader(XSS_PROTECTION_HEADER, headerValue); + } } /** diff --git a/web/src/main/java/org/springframework/security/web/header/writers/frameoptions/XFrameOptionsHeaderWriter.java b/web/src/main/java/org/springframework/security/web/header/writers/frameoptions/XFrameOptionsHeaderWriter.java index 6c7f77aaae..32291ca8e0 100644 --- a/web/src/main/java/org/springframework/security/web/header/writers/frameoptions/XFrameOptionsHeaderWriter.java +++ b/web/src/main/java/org/springframework/security/web/header/writers/frameoptions/XFrameOptionsHeaderWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletResponse; * * @author Marten Deinum * @author Rob Winch + * @author Ankur Pathak * @since 3.2 * * @see AllowFromStrategy @@ -84,10 +85,14 @@ public final class XFrameOptionsHeaderWriter implements HeaderWriter { if (XFrameOptionsMode.ALLOW_FROM.equals(frameOptionsMode)) { String allowFromValue = this.allowFromStrategy.getAllowFromValue(request); if (XFrameOptionsMode.DENY.getMode().equals(allowFromValue)) { - response.setHeader(XFRAME_OPTIONS_HEADER, XFrameOptionsMode.DENY.getMode()); + if (!response.containsHeader(XFRAME_OPTIONS_HEADER)) { + response.setHeader(XFRAME_OPTIONS_HEADER, XFrameOptionsMode.DENY.getMode()); + } } else if (allowFromValue != null) { - response.setHeader(XFRAME_OPTIONS_HEADER, - XFrameOptionsMode.ALLOW_FROM.getMode() + " " + allowFromValue); + if (!response.containsHeader(XFRAME_OPTIONS_HEADER)) { + response.setHeader(XFRAME_OPTIONS_HEADER, + XFrameOptionsMode.ALLOW_FROM.getMode() + " " + allowFromValue); + } } } else { diff --git a/web/src/test/java/org/springframework/security/web/header/writers/ContentSecurityPolicyHeaderWriterTests.java b/web/src/test/java/org/springframework/security/web/header/writers/ContentSecurityPolicyHeaderWriterTests.java index 616841535a..374be7f2bc 100644 --- a/web/src/test/java/org/springframework/security/web/header/writers/ContentSecurityPolicyHeaderWriterTests.java +++ b/web/src/test/java/org/springframework/security/web/header/writers/ContentSecurityPolicyHeaderWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -24,12 +24,16 @@ import static org.assertj.core.api.Assertions.assertThat; /** * @author Joe Grandja + * @author Ankur Pathak */ public class ContentSecurityPolicyHeaderWriterTests { private static final String DEFAULT_POLICY_DIRECTIVES = "default-src 'self'"; private MockHttpServletRequest request; private MockHttpServletResponse response; private ContentSecurityPolicyHeaderWriter writer; + private static final String CONTENT_SECURITY_POLICY_HEADER = "Content-Security-Policy"; + private static final String CONTENT_SECURITY_POLICY_REPORT_ONLY_HEADER = "Content-Security-Policy-Report-Only"; + @Before public void setup() { @@ -87,4 +91,21 @@ public class ContentSecurityPolicyHeaderWriterTests { writer = new ContentSecurityPolicyHeaderWriter(null); } -} \ No newline at end of file + + @Test + public void writeHeaderOnlyIfNotPresentContentSecurityPolicyHeader(){ + String value = new String("value"); + this.response.setHeader(CONTENT_SECURITY_POLICY_HEADER, value); + this.writer.writeHeaders(this.request, this.response); + assertThat(this.response.getHeader(CONTENT_SECURITY_POLICY_HEADER)).isSameAs(value); + } + + @Test + public void writeHeaderOnlyIfNotPresentContentSecurityPolicyReportOnlyHeader(){ + String value = new String("value"); + this.response.setHeader(CONTENT_SECURITY_POLICY_REPORT_ONLY_HEADER, value); + this.writer.setReportOnly(true); + this.writer.writeHeaders(this.request, this.response); + assertThat(this.response.getHeader(CONTENT_SECURITY_POLICY_REPORT_ONLY_HEADER)).isSameAs(value); + } +} diff --git a/web/src/test/java/org/springframework/security/web/header/writers/FeaturePolicyHeaderWriterTests.java b/web/src/test/java/org/springframework/security/web/header/writers/FeaturePolicyHeaderWriterTests.java index cf8b1fdecc..a507008c40 100644 --- a/web/src/test/java/org/springframework/security/web/header/writers/FeaturePolicyHeaderWriterTests.java +++ b/web/src/test/java/org/springframework/security/web/header/writers/FeaturePolicyHeaderWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; * Tests for {@link FeaturePolicyHeaderWriter}. * * @author Vedran Pavic + * @author Ankur Pathak */ public class FeaturePolicyHeaderWriterTests { @@ -40,6 +41,8 @@ public class FeaturePolicyHeaderWriterTests { private FeaturePolicyHeaderWriter writer; + private static final String FEATURE_POLICY_HEADER = "Feature-Policy"; + @Before public void setUp() { this.request = new MockHttpServletRequest(); @@ -70,4 +73,12 @@ public class FeaturePolicyHeaderWriterTests { .hasMessage("policyDirectives must not be null or empty"); } + @Test + public void writeHeaderOnlyIfNotPresent(){ + String value = new String("value"); + this.response.setHeader(FEATURE_POLICY_HEADER, value); + this.writer.writeHeaders(this.request, this.response); + assertThat(this.response.getHeader(FEATURE_POLICY_HEADER)).isSameAs(value); + } + } diff --git a/web/src/test/java/org/springframework/security/web/header/writers/HpkpHeaderWriterTests.java b/web/src/test/java/org/springframework/security/web/header/writers/HpkpHeaderWriterTests.java index e97e77148a..24a9bbe0f7 100644 --- a/web/src/test/java/org/springframework/security/web/header/writers/HpkpHeaderWriterTests.java +++ b/web/src/test/java/org/springframework/security/web/header/writers/HpkpHeaderWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -30,6 +30,7 @@ import org.springframework.mock.web.MockHttpServletResponse; /** * @author Tim Ysewyn + * @author Ankur Pathak * */ public class HpkpHeaderWriterTests { @@ -47,6 +48,10 @@ public class HpkpHeaderWriterTests { private HpkpHeaderWriter writer; + private static final String HPKP_HEADER_NAME = "Public-Key-Pins"; + + private static final String HPKP_RO_HEADER_NAME = "Public-Key-Pins-Report-Only"; + @Before public void setup() { request = new MockHttpServletRequest(); @@ -196,4 +201,22 @@ public class HpkpHeaderWriterTests { public void setIncorrectReportUri() { writer.setReportUri("some url here..."); } + + @Test + public void writeHeaderOnlyIfNotPresentPublicKeyPins(){ + String value = new String("value"); + this.response.setHeader(HPKP_HEADER_NAME, value); + this.writer.setReportOnly(false); + this.writer.writeHeaders(this.request, this.response); + assertThat(this.response.getHeader(HPKP_HEADER_NAME)).isSameAs(value); + } + + @Test + public void writeHeaderOnlyIfNotPresentPublicKeyPinsReportOnly(){ + String value = new String("value"); + this.response.setHeader(HPKP_RO_HEADER_NAME, value); + this.writer.setReportOnly(false); + this.writer.writeHeaders(this.request, this.response); + assertThat(this.response.getHeader(HPKP_RO_HEADER_NAME)).isSameAs(value); + } } diff --git a/web/src/test/java/org/springframework/security/web/header/writers/HstsHeaderWriterTests.java b/web/src/test/java/org/springframework/security/web/header/writers/HstsHeaderWriterTests.java index 7c7ab5d68a..de1f0558df 100644 --- a/web/src/test/java/org/springframework/security/web/header/writers/HstsHeaderWriterTests.java +++ b/web/src/test/java/org/springframework/security/web/header/writers/HstsHeaderWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -21,11 +21,11 @@ import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.security.web.header.writers.HstsHeaderWriter; import org.springframework.security.web.util.matcher.AnyRequestMatcher; /** * @author Rob Winch + * @author Ankur Pathak * */ public class HstsHeaderWriterTests { @@ -34,6 +34,8 @@ public class HstsHeaderWriterTests { private HstsHeaderWriter writer; + private static final String HSTS_HEADER_NAME = "Strict-Transport-Security"; + @Before public void setup() { request = new MockHttpServletRequest(); @@ -150,4 +152,12 @@ public class HstsHeaderWriterTests { public void setRequestMatcherToNull() { writer.setRequestMatcher(null); } + + @Test + public void writeHeaderOnlyIfNotPresent(){ + String value = new String("value"); + this.response.setHeader(HSTS_HEADER_NAME, value); + this.writer.writeHeaders(this.request, this.response); + assertThat(this.response.getHeader(HSTS_HEADER_NAME)).isSameAs(value); + } } diff --git a/web/src/test/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriterTests.java b/web/src/test/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriterTests.java index d13b80ba49..48a8741ed2 100644 --- a/web/src/test/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriterTests.java +++ b/web/src/test/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -22,10 +22,11 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.*; +import static org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy; /** * @author Eddú Meléndez + * @author Ankur Pathak */ public class ReferrerPolicyHeaderWriterTests { @@ -34,6 +35,8 @@ public class ReferrerPolicyHeaderWriterTests { private MockHttpServletResponse response; private ReferrerPolicyHeaderWriter writer; + private static final String REFERRER_POLICY_HEADER = "Referrer-Policy"; + @Before public void setup() { this.request = new MockHttpServletRequest(); @@ -65,4 +68,11 @@ public class ReferrerPolicyHeaderWriterTests { this.writer = new ReferrerPolicyHeaderWriter(null); } + @Test + public void writeHeaderOnlyIfNotPresent(){ + String value = new String("value"); + this.response.setHeader(REFERRER_POLICY_HEADER, value); + this.writer.writeHeaders(this.request, this.response); + assertThat(this.response.getHeader(REFERRER_POLICY_HEADER)).isSameAs(value); + } } diff --git a/web/src/test/java/org/springframework/security/web/header/writers/StaticHeaderWriterTests.java b/web/src/test/java/org/springframework/security/web/header/writers/StaticHeaderWriterTests.java index 4cd3d41d40..841dd9a4f1 100644 --- a/web/src/test/java/org/springframework/security/web/header/writers/StaticHeaderWriterTests.java +++ b/web/src/test/java/org/springframework/security/web/header/writers/StaticHeaderWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -25,13 +25,13 @@ import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.web.header.Header; -import org.springframework.security.web.header.writers.StaticHeadersWriter; /** * Test for the {@code StaticHeadersWriter} * * @author Marten Deinum * @author Rob Winch + * @author Ankur Pathak * @since 3.2 */ public class StaticHeaderWriterTests { @@ -96,4 +96,23 @@ public class StaticHeaderWriterTests { assertThat(response.getHeaderValues(cacheControl.getName())).isEqualTo( cacheControl.getValues()); } + + @Test + public void writeHeaderOnlyIfNotPresent() { + String pragmaValue = new String("pragmaValue"); + String cacheControlValue = new String("cacheControlValue"); + this.response.setHeader("Pragma", pragmaValue); + this.response.setHeader("Cache-Control", cacheControlValue); + Header pragma = new Header("Pragma", "no-cache"); + Header cacheControl = new Header("Cache-Control", "no-cache", "no-store", + "must-revalidate"); + StaticHeadersWriter factory = new StaticHeadersWriter(Arrays.asList(pragma, + cacheControl)); + factory.writeHeaders(this.request, this.response); + + assertThat(this.response.getHeaderNames()).hasSize(2); + assertThat(this.response.getHeader("Pragma")).isSameAs(pragmaValue); + assertThat(this.response.getHeader("Cache-Control")).isSameAs(cacheControlValue); + + } } diff --git a/web/src/test/java/org/springframework/security/web/header/writers/XXssProtectionHeaderWriterTests.java b/web/src/test/java/org/springframework/security/web/header/writers/XXssProtectionHeaderWriterTests.java index 65cf3e352b..dc19e17c0f 100644 --- a/web/src/test/java/org/springframework/security/web/header/writers/XXssProtectionHeaderWriterTests.java +++ b/web/src/test/java/org/springframework/security/web/header/writers/XXssProtectionHeaderWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -24,6 +24,7 @@ import org.springframework.mock.web.MockHttpServletResponse; /** * @author Rob Winch + * @author Ankur Pathak * */ public class XXssProtectionHeaderWriterTests { @@ -34,6 +35,8 @@ public class XXssProtectionHeaderWriterTests { private XXssProtectionHeaderWriter writer; + private static final String XSS_PROTECTION_HEADER = "X-XSS-Protection"; + @Before public void setup() { request = new MockHttpServletRequest(); @@ -87,4 +90,12 @@ public class XXssProtectionHeaderWriterTests { writer.setBlock(true); } + + @Test + public void writeHeaderOnlyIfNotPresent(){ + String value = new String("value"); + this.response.setHeader(XSS_PROTECTION_HEADER, value); + this.writer.writeHeaders(this.request, this.response); + assertThat(this.response.getHeader(XSS_PROTECTION_HEADER)).isSameAs(value); + } } diff --git a/web/src/test/java/org/springframework/security/web/header/writers/frameoptions/XFrameOptionsHeaderWriterTests.java b/web/src/test/java/org/springframework/security/web/header/writers/frameoptions/XFrameOptionsHeaderWriterTests.java index a4218e83d8..1e36e8ca86 100644 --- a/web/src/test/java/org/springframework/security/web/header/writers/frameoptions/XFrameOptionsHeaderWriterTests.java +++ b/web/src/test/java/org/springframework/security/web/header/writers/frameoptions/XFrameOptionsHeaderWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -21,17 +21,21 @@ import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import java.util.Arrays; +import java.util.Collections; import static org.assertj.core.api.Assertions.assertThat; /** * @author Rob Winch + * @author AnkurPathak * @since 5.0 */ public class XFrameOptionsHeaderWriterTests { private MockHttpServletRequest request = new MockHttpServletRequest(); private MockHttpServletResponse response = new MockHttpServletResponse(); + private static final String XFRAME_OPTIONS_HEADER = "X-Frame-Options"; + @Test public void writeHeadersWhenWhiteList() { WhiteListedAllowFromStrategy whitelist = new WhiteListedAllowFromStrategy(Arrays.asList("example.com")); @@ -43,4 +47,13 @@ public class XFrameOptionsHeaderWriterTests { assertThat(this.response.getHeaderValue(XFrameOptionsHeaderWriter.XFRAME_OPTIONS_HEADER)).isEqualTo("DENY"); } + @Test + public void writeHeaderOnlyIfNotPresent(){ + WhiteListedAllowFromStrategy whitelist = new WhiteListedAllowFromStrategy(Collections.singletonList("example.com")); + XFrameOptionsHeaderWriter writer = new XFrameOptionsHeaderWriter(whitelist); + String value = new String("value"); + this.response.setHeader(XFRAME_OPTIONS_HEADER, value); + writer.writeHeaders(this.request, this.response); + assertThat(this.response.getHeader(XFRAME_OPTIONS_HEADER)).isSameAs(value); + } }