Merge f06e8006ff
into 725745defd
This commit is contained in:
commit
33529a893b
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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
|
||||
* <paramter-value>.
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue