This commit is contained in:
Andrey Litvitski 2025-07-02 13:48:12 +09:00 committed by GitHub
commit 33529a893b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 12 additions and 795 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2025 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.
@ -16,7 +16,6 @@
package org.springframework.security.config.annotation.web.configurers;
import java.net.URI;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
@ -35,8 +34,6 @@ import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.header.writers.StaticHeadersWriter;
import org.springframework.security.web.header.writers.XXssProtectionHeaderWriter;
import org.springframework.security.web.header.writers.frameoptions.StaticAllowFromStrategy;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultMatcher;
@ -102,13 +99,6 @@ public class NamespaceHttpHeadersTests {
this.mvc.perform(get("/")).andExpect(includes(Collections.singletonMap("X-Frame-Options", "SAMEORIGIN")));
}
@Test
public void requestWhenFrameOptionsAllowFromThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(FrameOptionsAllowFromConfig.class).autowire();
this.mvc.perform(get("/"))
.andExpect(includes(Collections.singletonMap("X-Frame-Options", "ALLOW-FROM https://example.com")));
}
@Test
public void requestWhenXssOnlyThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(XssProtectionConfig.class).autowire();
@ -243,25 +233,6 @@ public class NamespaceHttpHeadersTests {
}
@Configuration
@EnableWebSecurity
static class FrameOptionsAllowFromConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers((headers) -> headers
// frame-options@ref
.defaultsDisabled()
.addHeaderWriter(new XFrameOptionsHeaderWriter(
new StaticAllowFromStrategy(URI.create("https://example.com")))));
return http.build();
// @formatter:on
}
}
@Configuration
@EnableWebSecurity
static class XssProtectionConfig {

View File

@ -1,81 +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
*
* https://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.web.header.writers.frameoptions;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.log.LogMessage;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Base class for AllowFromStrategy implementations which use a request parameter to
* retrieve the origin. By default the parameter named <code>x-frames-allow-from</code> is
* read from the request.
*
* @author Marten Deinum
* @since 3.2
* @deprecated ALLOW-FROM is an obsolete directive that no longer works in modern
* browsers. Instead use Content-Security-Policy with the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors">frame-ancestors</a>
* directive.
*/
@Deprecated
public abstract class AbstractRequestParameterAllowFromStrategy implements AllowFromStrategy {
private static final String DEFAULT_ORIGIN_REQUEST_PARAMETER = "x-frames-allow-from";
private String allowFromParameterName = DEFAULT_ORIGIN_REQUEST_PARAMETER;
/** Logger for use by subclasses */
protected final Log log = LogFactory.getLog(getClass());
AbstractRequestParameterAllowFromStrategy() {
}
@Override
public String getAllowFromValue(HttpServletRequest request) {
String allowFromOrigin = request.getParameter(this.allowFromParameterName);
this.log.debug(LogMessage.format("Supplied origin '%s'", allowFromOrigin));
if (StringUtils.hasText(allowFromOrigin) && allowed(allowFromOrigin)) {
return allowFromOrigin;
}
return "DENY";
}
/**
* Sets the HTTP parameter used to retrieve the value for the origin that is allowed
* from. The value of the parameter should be a valid URL. The default parameter name
* is "x-frames-allow-from".
* @param allowFromParameterName the name of the HTTP parameter to
*/
public void setAllowFromParameterName(String allowFromParameterName) {
Assert.notNull(allowFromParameterName, "allowFromParameterName cannot be null");
this.allowFromParameterName = allowFromParameterName;
}
/**
* Method to be implemented by base classes, used to determine if the supplied origin
* is allowed.
* @param allowFromOrigin the supplied origin
* @return <code>true</code> if the supplied origin is allowed.
*/
protected abstract boolean allowed(String allowFromOrigin);
}

View File

@ -1,44 +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
*
* https://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.web.header.writers.frameoptions;
import jakarta.servlet.http.HttpServletRequest;
/**
* Strategy interfaces used by the {@code FrameOptionsHeaderWriter} to determine the
* actual value to use for the X-Frame-Options header when using the ALLOW-FROM directive.
*
* @author Marten Deinum
* @since 3.2
* @deprecated ALLOW-FROM is an obsolete directive that no longer works in modern
* browsers. Instead use Content-Security-Policy with the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors">frame-ancestors</a>
* directive.
*/
@Deprecated
public interface AllowFromStrategy {
/**
* Gets the value for ALLOW-FROM excluding the ALLOW-FROM. For example, the result
* might be "https://example.com/".
* @param request the {@link HttpServletRequest}
* @return the value for ALLOW-FROM or null if no header should be added for this
* request.
*/
String getAllowFromValue(HttpServletRequest request);
}

View File

@ -1,55 +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
*
* https://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.web.header.writers.frameoptions;
import java.util.regex.Pattern;
import org.springframework.util.Assert;
/**
* Implementation which uses a regular expression to validate the supplied origin. If the
* value of the HTTP parameter matches the pattern, then the result will be ALLOW-FROM
* &lt;paramter-value&gt;.
*
* @author Marten Deinum
* @since 3.2
* @deprecated ALLOW-FROM is an obsolete directive that no longer works in modern
* browsers. Instead use Content-Security-Policy with the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors">frame-ancestors</a>
* directive.
*/
@Deprecated
public final class RegExpAllowFromStrategy extends AbstractRequestParameterAllowFromStrategy {
private final Pattern pattern;
/**
* Creates a new instance
* @param pattern the Pattern to compare against the HTTP parameter value. If the
* pattern matches, the domain will be allowed, else denied.
*/
public RegExpAllowFromStrategy(String pattern) {
Assert.hasText(pattern, "Pattern cannot be empty.");
this.pattern = Pattern.compile(pattern);
}
@Override
protected boolean allowed(String allowFromOrigin) {
return this.pattern.matcher(allowFromOrigin).matches();
}
}

View File

@ -1,45 +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
*
* https://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.web.header.writers.frameoptions;
import java.net.URI;
import jakarta.servlet.http.HttpServletRequest;
/**
* Simple implementation of the {@code AllowFromStrategy}
*
* @deprecated ALLOW-FROM is an obsolete directive that no longer works in modern
* browsers. Instead use Content-Security-Policy with the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors">frame-ancestors</a>
* directive.
*/
@Deprecated
public final class StaticAllowFromStrategy implements AllowFromStrategy {
private final URI uri;
public StaticAllowFromStrategy(URI uri) {
this.uri = uri;
}
@Override
public String getAllowFromValue(HttpServletRequest request) {
return this.uri.toString();
}
}

View File

@ -1,52 +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
*
* https://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.web.header.writers.frameoptions;
import java.util.Collection;
import org.springframework.util.Assert;
/**
* Implementation which checks the supplied origin against a list of allowed origins.
*
* @author Marten Deinum
* @since 3.2
* @deprecated ALLOW-FROM is an obsolete directive that no longer works in modern
* browsers. Instead use Content-Security-Policy with the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors">frame-ancestors</a>
* directive.
*/
@Deprecated
public final class WhiteListedAllowFromStrategy extends AbstractRequestParameterAllowFromStrategy {
private final Collection<String> allowed;
/**
* Creates a new instance
* @param allowed the origins that are allowed.
*/
public WhiteListedAllowFromStrategy(Collection<String> allowed) {
Assert.notEmpty(allowed, "Allowed origins cannot be empty.");
this.allowed = allowed;
}
@Override
protected boolean allowed(String allowFromOrigin) {
return this.allowed.contains(allowFromOrigin);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2025 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.
@ -23,8 +23,7 @@ import org.springframework.security.web.header.HeaderWriter;
import org.springframework.util.Assert;
/**
* {@code HeaderWriter} implementation for the X-Frame-Options headers. When using the
* ALLOW-FROM directive the actual value is determined by a {@code AllowFromStrategy}.
* {@code HeaderWriter} implementation for the X-Frame-Options headers.
*
* @author Marten Deinum
* @author Rob Winch
@ -35,8 +34,6 @@ public final class XFrameOptionsHeaderWriter implements HeaderWriter {
public static final String XFRAME_OPTIONS_HEADER = "X-Frame-Options";
private final AllowFromStrategy allowFromStrategy;
private final XFrameOptionsMode frameOptionsMode;
/**
@ -49,34 +46,10 @@ public final class XFrameOptionsHeaderWriter implements HeaderWriter {
/**
* Creates a new instance
* @param frameOptionsMode the {@link XFrameOptionsMode} to use. If using
* {@link XFrameOptionsMode#ALLOW_FROM}, use Content-Security-Policy with the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors">frame-ancestors</a>
* directive instead.
*/
public XFrameOptionsHeaderWriter(XFrameOptionsMode frameOptionsMode) {
Assert.notNull(frameOptionsMode, "frameOptionsMode cannot be null");
Assert.isTrue(!XFrameOptionsMode.ALLOW_FROM.equals(frameOptionsMode),
"ALLOW_FROM requires an AllowFromStrategy. Please use "
+ "FrameOptionsHeaderWriter(AllowFromStrategy allowFromStrategy) instead");
this.frameOptionsMode = frameOptionsMode;
this.allowFromStrategy = null;
}
/**
* Creates a new instance with {@link XFrameOptionsMode#ALLOW_FROM}.
* @param allowFromStrategy the strategy for determining what the value for ALLOW_FROM
* is.
* @deprecated ALLOW-FROM is an obsolete directive that no longer works in modern
* browsers. Instead use Content-Security-Policy with the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors">frame-ancestors</a>
* directive.
* @see AllowFromStrategy
*/
@Deprecated
public XFrameOptionsHeaderWriter(AllowFromStrategy allowFromStrategy) {
Assert.notNull(allowFromStrategy, "allowFromStrategy cannot be null");
this.frameOptionsMode = XFrameOptionsMode.ALLOW_FROM;
this.allowFromStrategy = allowFromStrategy;
}
/**
@ -86,23 +59,7 @@ public final class XFrameOptionsHeaderWriter implements HeaderWriter {
*/
@Override
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
if (XFrameOptionsMode.ALLOW_FROM.equals(this.frameOptionsMode)) {
String allowFromValue = this.allowFromStrategy.getAllowFromValue(request);
if (XFrameOptionsMode.DENY.getMode().equals(allowFromValue)) {
if (!response.containsHeader(XFRAME_OPTIONS_HEADER)) {
response.setHeader(XFRAME_OPTIONS_HEADER, XFrameOptionsMode.DENY.getMode());
}
}
else if (allowFromValue != null) {
if (!response.containsHeader(XFRAME_OPTIONS_HEADER)) {
response.setHeader(XFRAME_OPTIONS_HEADER,
XFrameOptionsMode.ALLOW_FROM.getMode() + " " + allowFromValue);
}
}
}
else {
response.setHeader(XFRAME_OPTIONS_HEADER, this.frameOptionsMode.getMode());
}
response.setHeader(XFRAME_OPTIONS_HEADER, this.frameOptionsMode.getMode());
}
/**
@ -115,16 +72,7 @@ public final class XFrameOptionsHeaderWriter implements HeaderWriter {
DENY("DENY"),
SAMEORIGIN("SAMEORIGIN"),
/**
* @deprecated ALLOW-FROM is an obsolete directive that no longer works in modern
* browsers. Instead use Content-Security-Policy with the <a href=
* "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors">frame-ancestors</a>
* directive.
*/
@Deprecated
ALLOW_FROM("ALLOW-FROM");
SAMEORIGIN("SAMEORIGIN");
private final String mode;
@ -134,7 +82,7 @@ public final class XFrameOptionsHeaderWriter implements HeaderWriter {
/**
* Gets the mode for the X-Frame-Options header value. For example, DENY,
* SAMEORIGIN, ALLOW-FROM. Cannot be null.
* SAMEORIGIN. Cannot be null.
* @return the mode for the X-Frame-Options header value.
*/
private String getMode() {

View File

@ -1,92 +0,0 @@
/*
* Copyright 2002-2013 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
*
* https://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.web.header.writers.frameoptions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Rob Winch
*
*/
public class AbstractRequestParameterAllowFromStrategyTests {
private MockHttpServletRequest request;
@BeforeEach
public void setup() {
this.request = new MockHttpServletRequest();
}
@Test
public void nullAllowFromParameterValue() {
RequestParameterAllowFromStrategyStub strategy = new RequestParameterAllowFromStrategyStub(true);
assertThat(strategy.getAllowFromValue(this.request)).isEqualTo("DENY");
}
@Test
public void emptyAllowFromParameterValue() {
this.request.setParameter("x-frames-allow-from", "");
RequestParameterAllowFromStrategyStub strategy = new RequestParameterAllowFromStrategyStub(true);
assertThat(strategy.getAllowFromValue(this.request)).isEqualTo("DENY");
}
@Test
public void emptyAllowFromCustomParameterValue() {
String customParam = "custom";
this.request.setParameter(customParam, "");
RequestParameterAllowFromStrategyStub strategy = new RequestParameterAllowFromStrategyStub(true);
strategy.setAllowFromParameterName(customParam);
assertThat(strategy.getAllowFromValue(this.request)).isEqualTo("DENY");
}
@Test
public void allowFromParameterValueAllowed() {
String value = "https://example.com";
this.request.setParameter("x-frames-allow-from", value);
RequestParameterAllowFromStrategyStub strategy = new RequestParameterAllowFromStrategyStub(true);
assertThat(strategy.getAllowFromValue(this.request)).isEqualTo(value);
}
@Test
public void allowFromParameterValueDenied() {
String value = "https://example.com";
this.request.setParameter("x-frames-allow-from", value);
RequestParameterAllowFromStrategyStub strategy = new RequestParameterAllowFromStrategyStub(false);
assertThat(strategy.getAllowFromValue(this.request)).isEqualTo("DENY");
}
private static class RequestParameterAllowFromStrategyStub extends AbstractRequestParameterAllowFromStrategy {
private boolean match;
RequestParameterAllowFromStrategyStub(boolean match) {
this.match = match;
}
@Override
protected boolean allowed(String allowFromOrigin) {
return this.match;
}
}
}

View File

@ -1,115 +0,0 @@
/*
* Copyright 2002-2017 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
*
* https://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.web.header.writers.frameoptions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter.XFrameOptionsMode;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.BDDMockito.given;
/**
* @author Rob Winch
*
*/
@ExtendWith(MockitoExtension.class)
public class FrameOptionsHeaderWriterTests {
@Mock
private AllowFromStrategy strategy;
private MockHttpServletResponse response;
private MockHttpServletRequest request;
private XFrameOptionsHeaderWriter writer;
@BeforeEach
public void setup() {
this.request = new MockHttpServletRequest();
this.response = new MockHttpServletResponse();
}
@Test
public void constructorNullMode() {
assertThatIllegalArgumentException().isThrownBy(() -> new XFrameOptionsHeaderWriter((XFrameOptionsMode) null));
}
@Test
public void constructorAllowFromNoAllowFromStrategy() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new XFrameOptionsHeaderWriter(XFrameOptionsMode.ALLOW_FROM));
}
@Test
public void constructorNullAllowFromStrategy() {
assertThatIllegalArgumentException().isThrownBy(() -> new XFrameOptionsHeaderWriter((AllowFromStrategy) null));
}
@Test
public void writeHeadersAllowFromReturnsNull() {
this.writer = new XFrameOptionsHeaderWriter(this.strategy);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).isEmpty();
}
@Test
public void writeHeadersAllowFrom() {
String allowFromValue = "https://example.com/";
given(this.strategy.getAllowFromValue(this.request)).willReturn(allowFromValue);
this.writer = new XFrameOptionsHeaderWriter(this.strategy);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).hasSize(1);
assertThat(this.response.getHeader(XFrameOptionsHeaderWriter.XFRAME_OPTIONS_HEADER))
.isEqualTo("ALLOW-FROM " + allowFromValue);
}
@Test
public void writeHeadersDeny() {
this.writer = new XFrameOptionsHeaderWriter(XFrameOptionsMode.DENY);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).hasSize(1);
assertThat(this.response.getHeader(XFrameOptionsHeaderWriter.XFRAME_OPTIONS_HEADER)).isEqualTo("DENY");
}
@Test
public void writeHeadersSameOrigin() {
this.writer = new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).hasSize(1);
assertThat(this.response.getHeader(XFrameOptionsHeaderWriter.XFRAME_OPTIONS_HEADER)).isEqualTo("SAMEORIGIN");
}
@Test
public void writeHeadersTwiceLastWins() {
this.writer = new XFrameOptionsHeaderWriter(XFrameOptionsMode.SAMEORIGIN);
this.writer.writeHeaders(this.request, this.response);
this.writer = new XFrameOptionsHeaderWriter(XFrameOptionsMode.DENY);
this.writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderNames()).hasSize(1);
assertThat(this.response.getHeader(XFrameOptionsHeaderWriter.XFRAME_OPTIONS_HEADER)).isEqualTo("DENY");
}
}

View File

@ -1,68 +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
*
* https://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.web.header.writers.frameoptions;
import java.util.regex.PatternSyntaxException;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* @author Marten Deinum
*/
public class RegExpAllowFromStrategyTests {
@Test
public void invalidRegularExpressionShouldLeadToException() {
assertThatExceptionOfType(PatternSyntaxException.class).isThrownBy(() -> new RegExpAllowFromStrategy("[a-z"));
}
@Test
public void nullRegularExpressionShouldLeadToException() {
assertThatIllegalArgumentException().isThrownBy(() -> new RegExpAllowFromStrategy(null));
}
@Test
public void subdomainMatchingRegularExpression() {
RegExpAllowFromStrategy strategy = new RegExpAllowFromStrategy("^https://([a-z0-9]*?\\.)test\\.com");
strategy.setAllowFromParameterName("from");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setParameter("from", "https://www.test.com");
String result1 = strategy.getAllowFromValue(request);
assertThat(result1).isEqualTo("https://www.test.com");
request.setParameter("from", "https://www.test.com");
String result2 = strategy.getAllowFromValue(request);
assertThat(result2).isEqualTo("https://www.test.com");
request.setParameter("from", "https://test.foobar.com");
String result3 = strategy.getAllowFromValue(request);
assertThat(result3).isEqualTo("DENY");
}
@Test
public void noParameterShouldDeny() {
RegExpAllowFromStrategy strategy = new RegExpAllowFromStrategy("^https://([a-z0-9]*?\\.)test\\.com");
MockHttpServletRequest request = new MockHttpServletRequest();
String result1 = strategy.getAllowFromValue(request);
assertThat(result1).isEqualTo("DENY");
}
}

View File

@ -1,42 +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
*
* https://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.web.header.writers.frameoptions;
import java.net.URI;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Test for the StaticAllowFromStrategy.
*
* @author Marten Deinum
* @since 3.2
*/
public class StaticAllowFromStrategyTests {
@Test
public void shouldReturnUri() {
String uri = "https://www.test.com";
StaticAllowFromStrategy strategy = new StaticAllowFromStrategy(URI.create(uri));
assertThat(strategy.getAllowFromValue(new MockHttpServletRequest())).isEqualTo(uri);
}
}

View File

@ -1,95 +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
*
* https://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.web.header.writers.frameoptions;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Test for the {@code WhiteListedAllowFromStrategy}.
*
* @author Marten Deinum
* @since 3.2
*/
public class WhiteListedAllowFromStrategyTests {
@Test
public void emptyListShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> new WhiteListedAllowFromStrategy(new ArrayList<>()));
}
@Test
public void nullListShouldThrowException() {
assertThatIllegalArgumentException().isThrownBy(() -> new WhiteListedAllowFromStrategy(null));
}
@Test
public void listWithSingleElementShouldMatch() {
List<String> allowed = new ArrayList<>();
allowed.add("https://www.test.com");
WhiteListedAllowFromStrategy strategy = new WhiteListedAllowFromStrategy(allowed);
strategy.setAllowFromParameterName("from");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setParameter("from", "https://www.test.com");
String result = strategy.getAllowFromValue(request);
assertThat(result).isEqualTo("https://www.test.com");
}
@Test
public void listWithMultipleElementShouldMatch() {
List<String> allowed = new ArrayList<>();
allowed.add("https://www.test.com");
allowed.add("https://www.springsource.org");
WhiteListedAllowFromStrategy strategy = new WhiteListedAllowFromStrategy(allowed);
strategy.setAllowFromParameterName("from");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setParameter("from", "https://www.test.com");
String result = strategy.getAllowFromValue(request);
assertThat(result).isEqualTo("https://www.test.com");
}
@Test
public void listWithSingleElementShouldNotMatch() {
List<String> allowed = new ArrayList<>();
allowed.add("https://www.test.com");
WhiteListedAllowFromStrategy strategy = new WhiteListedAllowFromStrategy(allowed);
strategy.setAllowFromParameterName("from");
MockHttpServletRequest request = new MockHttpServletRequest();
request.setParameter("from", "https://www.test123.com");
String result = strategy.getAllowFromValue(request);
assertThat(result).isEqualTo("DENY");
}
@Test
public void requestWithoutParameterShouldNotMatch() {
List<String> allowed = new ArrayList<>();
allowed.add("https://www.test.com");
WhiteListedAllowFromStrategy strategy = new WhiteListedAllowFromStrategy(allowed);
strategy.setAllowFromParameterName("from");
MockHttpServletRequest request = new MockHttpServletRequest();
String result = strategy.getAllowFromValue(request);
assertThat(result).isEqualTo("DENY");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2025 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.
@ -16,9 +16,6 @@
package org.springframework.security.web.header.writers.frameoptions;
import java.util.Arrays;
import java.util.Collections;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
@ -29,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Rob Winch
* @author Ankur Pathak
* @author Andrey Litvitski
* @since 5.0
*/
public class XFrameOptionsHeaderWriterTests {
@ -40,22 +38,11 @@ public class XFrameOptionsHeaderWriterTests {
private static final String XFRAME_OPTIONS_HEADER = "X-Frame-Options";
@Test
public void writeHeadersWhenWhiteList() {
WhiteListedAllowFromStrategy whitelist = new WhiteListedAllowFromStrategy(Arrays.asList("example.com"));
XFrameOptionsHeaderWriter writer = new XFrameOptionsHeaderWriter(whitelist);
public void writeHeader() {
XFrameOptionsHeaderWriter writer = new XFrameOptionsHeaderWriter(
XFrameOptionsHeaderWriter.XFrameOptionsMode.DENY);
writer.writeHeaders(this.request, this.response);
assertThat(this.response.getHeaderValue(XFrameOptionsHeaderWriter.XFRAME_OPTIONS_HEADER)).isEqualTo("DENY");
}
@Test
public void writeHeaderWhenNotPresent() {
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);
assertThat(this.response.getHeader(XFRAME_OPTIONS_HEADER)).isEqualTo("DENY");
}
}