Consider having HeaderWriters check before writing

All HeadersWriter only write Header if its not already
written.

Fixes: gh-6454 gh-5193
This commit is contained in:
Ankur Pathak 2019-02-06 14:04:35 +05:30 committed by Josh Cummings
parent 4742c18e4b
commit 93d6a38ffd
No known key found for this signature in database
GPG Key ID: 49EF60DD7FF83443
16 changed files with 178 additions and 32 deletions

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -73,6 +73,7 @@ import javax.servlet.http.HttpServletResponse;
* </p> * </p>
* *
* @author Joe Grandja * @author Joe Grandja
* @author Ankur Pathak
* @since 4.1 * @since 4.1
*/ */
public final class ContentSecurityPolicyHeaderWriter implements HeaderWriter { public final class ContentSecurityPolicyHeaderWriter implements HeaderWriter {
@ -100,7 +101,10 @@ public final class ContentSecurityPolicyHeaderWriter implements HeaderWriter {
*/ */
@Override @Override
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { 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);
}
} }
/** /**

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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. * responsible for declaring the restrictions for a particular feature type.
* *
* @author Vedran Pavic * @author Vedran Pavic
* @author Ankur Pathak
* @since 5.1 * @since 5.1
*/ */
public final class FeaturePolicyHeaderWriter implements HeaderWriter { public final class FeaturePolicyHeaderWriter implements HeaderWriter {
@ -54,8 +55,10 @@ public final class FeaturePolicyHeaderWriter implements HeaderWriter {
@Override @Override
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
if (!response.containsHeader(FEATURE_POLICY_HEADER)) {
response.setHeader(FEATURE_POLICY_HEADER, this.policyDirectives); response.setHeader(FEATURE_POLICY_HEADER, this.policyDirectives);
} }
}
/** /**
* Set the security policy directive(s) to be used in the response header. * Set the security policy directive(s) to be used in the response header.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -100,6 +100,7 @@ import java.util.Map;
* </p> * </p>
* *
* @author Tim Ysewyn * @author Tim Ysewyn
* @author Ankur Pathak
* @since 4.1 * @since 4.1
*/ */
public final class HpkpHeaderWriter implements HeaderWriter { public final class HpkpHeaderWriter implements HeaderWriter {
@ -174,7 +175,10 @@ public final class HpkpHeaderWriter implements HeaderWriter {
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
if (requestMatcher.matches(request)) { if (requestMatcher.matches(request)) {
if (!pins.isEmpty()) { 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()) { } if (logger.isDebugEnabled()) {
logger.debug("Not injecting HPKP header since there aren't any pins"); logger.debug("Not injecting HPKP header since there aren't any pins");
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -53,6 +53,7 @@ import org.springframework.util.Assert;
* </p> * </p>
* *
* @author Rob Winch * @author Rob Winch
* @author Ankur Pathak
* @since 3.2 * @since 3.2
*/ */
public final class HstsHeaderWriter implements HeaderWriter { public final class HstsHeaderWriter implements HeaderWriter {
@ -159,8 +160,10 @@ public final class HstsHeaderWriter implements HeaderWriter {
*/ */
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
if (this.requestMatcher.matches(request)) { if (this.requestMatcher.matches(request)) {
if (!response.containsHeader(HSTS_HEADER_NAME)) {
response.setHeader(HSTS_HEADER_NAME, this.hstsHeaderValue); response.setHeader(HSTS_HEADER_NAME, this.hstsHeaderValue);
} }
}
else if (this.logger.isDebugEnabled()) { else if (this.logger.isDebugEnabled()) {
this.logger this.logger
.debug("Not injecting HSTS header since it did not match the requestMatcher " .debug("Not injecting HSTS header since it did not match the requestMatcher "

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 Eddú Meléndez
* @author Kazuki Shimizu * @author Kazuki Shimizu
* @author Ankur Pathak
* @since 4.2 * @since 4.2
*/ */
public class ReferrerPolicyHeaderWriter implements HeaderWriter { public class ReferrerPolicyHeaderWriter implements HeaderWriter {
@ -89,8 +90,10 @@ public class ReferrerPolicyHeaderWriter implements HeaderWriter {
*/ */
@Override @Override
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
if (!response.containsHeader(REFERRER_POLICY_HEADER)) {
response.setHeader(REFERRER_POLICY_HEADER, this.policy.getPolicy()); response.setHeader(REFERRER_POLICY_HEADER, this.policy.getPolicy());
} }
}
public enum ReferrerPolicy { public enum ReferrerPolicy {

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 Marten Deinum
* @author Rob Winch * @author Rob Winch
* @author Ankur Pathak
* @since 3.2 * @since 3.2
*/ */
public class StaticHeadersWriter implements HeaderWriter { public class StaticHeadersWriter implements HeaderWriter {
@ -56,11 +57,13 @@ public class StaticHeadersWriter implements HeaderWriter {
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
for (Header header : headers) { for (Header header : headers) {
if (!response.containsHeader(header.getName())) {
for (String value : header.getValues()) { for (String value : header.getValues()) {
response.addHeader(header.getName(), value); response.addHeader(header.getName(), value);
} }
} }
} }
}
@Override @Override
public String toString() { public String toString() {

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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>. * >X-XSS-Protection header</a>.
* *
* @author Rob Winch * @author Rob Winch
* @author Ankur Pathak
* @since 3.2 * @since 3.2
*/ */
public final class XXssProtectionHeaderWriter implements HeaderWriter { public final class XXssProtectionHeaderWriter implements HeaderWriter {
@ -47,8 +48,10 @@ public final class XXssProtectionHeaderWriter implements HeaderWriter {
} }
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) { public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
if (!response.containsHeader(XSS_PROTECTION_HEADER)) {
response.setHeader(XSS_PROTECTION_HEADER, headerValue); response.setHeader(XSS_PROTECTION_HEADER, headerValue);
} }
}
/** /**
* If true, will contain a value of 1. For example: * If true, will contain a value of 1. For example:

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 Marten Deinum
* @author Rob Winch * @author Rob Winch
* @author Ankur Pathak
* @since 3.2 * @since 3.2
* *
* @see AllowFromStrategy * @see AllowFromStrategy
@ -84,12 +85,16 @@ public final class XFrameOptionsHeaderWriter implements HeaderWriter {
if (XFrameOptionsMode.ALLOW_FROM.equals(frameOptionsMode)) { if (XFrameOptionsMode.ALLOW_FROM.equals(frameOptionsMode)) {
String allowFromValue = this.allowFromStrategy.getAllowFromValue(request); String allowFromValue = this.allowFromStrategy.getAllowFromValue(request);
if (XFrameOptionsMode.DENY.getMode().equals(allowFromValue)) { if (XFrameOptionsMode.DENY.getMode().equals(allowFromValue)) {
if (!response.containsHeader(XFRAME_OPTIONS_HEADER)) {
response.setHeader(XFRAME_OPTIONS_HEADER, XFrameOptionsMode.DENY.getMode()); response.setHeader(XFRAME_OPTIONS_HEADER, XFrameOptionsMode.DENY.getMode());
}
} else if (allowFromValue != null) { } else if (allowFromValue != null) {
if (!response.containsHeader(XFRAME_OPTIONS_HEADER)) {
response.setHeader(XFRAME_OPTIONS_HEADER, response.setHeader(XFRAME_OPTIONS_HEADER,
XFrameOptionsMode.ALLOW_FROM.getMode() + " " + allowFromValue); XFrameOptionsMode.ALLOW_FROM.getMode() + " " + allowFromValue);
} }
} }
}
else { else {
response.setHeader(XFRAME_OPTIONS_HEADER, frameOptionsMode.getMode()); response.setHeader(XFRAME_OPTIONS_HEADER, frameOptionsMode.getMode());
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 Joe Grandja
* @author Ankur Pathak
*/ */
public class ContentSecurityPolicyHeaderWriterTests { public class ContentSecurityPolicyHeaderWriterTests {
private static final String DEFAULT_POLICY_DIRECTIVES = "default-src 'self'"; private static final String DEFAULT_POLICY_DIRECTIVES = "default-src 'self'";
private MockHttpServletRequest request; private MockHttpServletRequest request;
private MockHttpServletResponse response; private MockHttpServletResponse response;
private ContentSecurityPolicyHeaderWriter writer; 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 @Before
public void setup() { public void setup() {
@ -87,4 +91,21 @@ public class ContentSecurityPolicyHeaderWriterTests {
writer = new ContentSecurityPolicyHeaderWriter(null); 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);
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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}. * Tests for {@link FeaturePolicyHeaderWriter}.
* *
* @author Vedran Pavic * @author Vedran Pavic
* @author Ankur Pathak
*/ */
public class FeaturePolicyHeaderWriterTests { public class FeaturePolicyHeaderWriterTests {
@ -40,6 +41,8 @@ public class FeaturePolicyHeaderWriterTests {
private FeaturePolicyHeaderWriter writer; private FeaturePolicyHeaderWriter writer;
private static final String FEATURE_POLICY_HEADER = "Feature-Policy";
@Before @Before
public void setUp() { public void setUp() {
this.request = new MockHttpServletRequest(); this.request = new MockHttpServletRequest();
@ -70,4 +73,12 @@ public class FeaturePolicyHeaderWriterTests {
.hasMessage("policyDirectives must not be null or empty"); .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);
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 Tim Ysewyn
* @author Ankur Pathak
* *
*/ */
public class HpkpHeaderWriterTests { public class HpkpHeaderWriterTests {
@ -47,6 +48,10 @@ public class HpkpHeaderWriterTests {
private HpkpHeaderWriter writer; 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 @Before
public void setup() { public void setup() {
request = new MockHttpServletRequest(); request = new MockHttpServletRequest();
@ -196,4 +201,22 @@ public class HpkpHeaderWriterTests {
public void setIncorrectReportUri() { public void setIncorrectReportUri() {
writer.setReportUri("some url here..."); 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);
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.header.writers.HstsHeaderWriter;
import org.springframework.security.web.util.matcher.AnyRequestMatcher; import org.springframework.security.web.util.matcher.AnyRequestMatcher;
/** /**
* @author Rob Winch * @author Rob Winch
* @author Ankur Pathak
* *
*/ */
public class HstsHeaderWriterTests { public class HstsHeaderWriterTests {
@ -34,6 +34,8 @@ public class HstsHeaderWriterTests {
private HstsHeaderWriter writer; private HstsHeaderWriter writer;
private static final String HSTS_HEADER_NAME = "Strict-Transport-Security";
@Before @Before
public void setup() { public void setup() {
request = new MockHttpServletRequest(); request = new MockHttpServletRequest();
@ -150,4 +152,12 @@ public class HstsHeaderWriterTests {
public void setRequestMatcherToNull() { public void setRequestMatcherToNull() {
writer.setRequestMatcher(null); 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);
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 org.springframework.mock.web.MockHttpServletResponse;
import static org.assertj.core.api.Assertions.assertThat; 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 Eddú Meléndez
* @author Ankur Pathak
*/ */
public class ReferrerPolicyHeaderWriterTests { public class ReferrerPolicyHeaderWriterTests {
@ -34,6 +35,8 @@ public class ReferrerPolicyHeaderWriterTests {
private MockHttpServletResponse response; private MockHttpServletResponse response;
private ReferrerPolicyHeaderWriter writer; private ReferrerPolicyHeaderWriter writer;
private static final String REFERRER_POLICY_HEADER = "Referrer-Policy";
@Before @Before
public void setup() { public void setup() {
this.request = new MockHttpServletRequest(); this.request = new MockHttpServletRequest();
@ -65,4 +68,11 @@ public class ReferrerPolicyHeaderWriterTests {
this.writer = new ReferrerPolicyHeaderWriter(null); 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);
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.header.Header; import org.springframework.security.web.header.Header;
import org.springframework.security.web.header.writers.StaticHeadersWriter;
/** /**
* Test for the {@code StaticHeadersWriter} * Test for the {@code StaticHeadersWriter}
* *
* @author Marten Deinum * @author Marten Deinum
* @author Rob Winch * @author Rob Winch
* @author Ankur Pathak
* @since 3.2 * @since 3.2
*/ */
public class StaticHeaderWriterTests { public class StaticHeaderWriterTests {
@ -96,4 +96,23 @@ public class StaticHeaderWriterTests {
assertThat(response.getHeaderValues(cacheControl.getName())).isEqualTo( assertThat(response.getHeaderValues(cacheControl.getName())).isEqualTo(
cacheControl.getValues()); 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);
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 Rob Winch
* @author Ankur Pathak
* *
*/ */
public class XXssProtectionHeaderWriterTests { public class XXssProtectionHeaderWriterTests {
@ -34,6 +35,8 @@ public class XXssProtectionHeaderWriterTests {
private XXssProtectionHeaderWriter writer; private XXssProtectionHeaderWriter writer;
private static final String XSS_PROTECTION_HEADER = "X-XSS-Protection";
@Before @Before
public void setup() { public void setup() {
request = new MockHttpServletRequest(); request = new MockHttpServletRequest();
@ -87,4 +90,12 @@ public class XXssProtectionHeaderWriterTests {
writer.setBlock(true); 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);
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 org.springframework.mock.web.MockHttpServletResponse;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
* @author Rob Winch * @author Rob Winch
* @author AnkurPathak
* @since 5.0 * @since 5.0
*/ */
public class XFrameOptionsHeaderWriterTests { public class XFrameOptionsHeaderWriterTests {
private MockHttpServletRequest request = new MockHttpServletRequest(); private MockHttpServletRequest request = new MockHttpServletRequest();
private MockHttpServletResponse response = new MockHttpServletResponse(); private MockHttpServletResponse response = new MockHttpServletResponse();
private static final String XFRAME_OPTIONS_HEADER = "X-Frame-Options";
@Test @Test
public void writeHeadersWhenWhiteList() { public void writeHeadersWhenWhiteList() {
WhiteListedAllowFromStrategy whitelist = new WhiteListedAllowFromStrategy(Arrays.asList("example.com")); 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"); 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);
}
} }