Bläddra i källkod

Consider having HeaderWriters check before writing

All HeadersWriter only write Header if its not already
written.

Fixes: gh-6454 gh-5193
Ankur Pathak 6 år sedan
förälder
incheckning
93d6a38ffd
16 ändrade filer med 178 tillägg och 32 borttagningar
  1. 6 2
      web/src/main/java/org/springframework/security/web/header/writers/ContentSecurityPolicyHeaderWriter.java
  2. 5 2
      web/src/main/java/org/springframework/security/web/header/writers/FeaturePolicyHeaderWriter.java
  3. 6 2
      web/src/main/java/org/springframework/security/web/header/writers/HpkpHeaderWriter.java
  4. 5 2
      web/src/main/java/org/springframework/security/web/header/writers/HstsHeaderWriter.java
  5. 5 2
      web/src/main/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriter.java
  6. 7 4
      web/src/main/java/org/springframework/security/web/header/writers/StaticHeadersWriter.java
  7. 5 2
      web/src/main/java/org/springframework/security/web/header/writers/XXssProtectionHeaderWriter.java
  8. 9 4
      web/src/main/java/org/springframework/security/web/header/writers/frameoptions/XFrameOptionsHeaderWriter.java
  9. 23 2
      web/src/test/java/org/springframework/security/web/header/writers/ContentSecurityPolicyHeaderWriterTests.java
  10. 12 1
      web/src/test/java/org/springframework/security/web/header/writers/FeaturePolicyHeaderWriterTests.java
  11. 24 1
      web/src/test/java/org/springframework/security/web/header/writers/HpkpHeaderWriterTests.java
  12. 12 2
      web/src/test/java/org/springframework/security/web/header/writers/HstsHeaderWriterTests.java
  13. 12 2
      web/src/test/java/org/springframework/security/web/header/writers/ReferrerPolicyHeaderWriterTests.java
  14. 21 2
      web/src/test/java/org/springframework/security/web/header/writers/StaticHeaderWriterTests.java
  15. 12 1
      web/src/test/java/org/springframework/security/web/header/writers/XXssProtectionHeaderWriterTests.java
  16. 14 1
      web/src/test/java/org/springframework/security/web/header/writers/frameoptions/XFrameOptionsHeaderWriterTests.java

+ 6 - 2
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;
  * </p>
  *
  * @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);
+		}
 	}
 
 	/**

+ 5 - 2
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);
+		}
 	}
 
 	/**

+ 6 - 2
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;
  * </p>
  *
  * @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");
 			}

+ 5 - 2
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;
  * </p>
  *
  * @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

+ 5 - 2
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 {

+ 7 - 4
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 + "]";
 	}
-}
+}

+ 5 - 2
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</a>.
  *
  * @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);
+		}
 	}
 
 	/**

+ 9 - 4
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 {

+ 23 - 2
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);
 	}
 
-}
+
+	@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);
+	}
+}

+ 12 - 1
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);
+	}
+
 }

+ 24 - 1
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);
+	}
 }

+ 12 - 2
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);
+	}
 }

+ 12 - 2
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);
+	}
 }

+ 21 - 2
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);
+
+	}
 }

+ 12 - 1
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);
+	}
 }

+ 14 - 1
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);
+	}
 }