Merge branch '7.0.x'
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
package org.springframework.security.web;
|
package org.springframework.security.web;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@@ -30,6 +31,7 @@ import org.springframework.security.crypto.keygen.Base64StringKeyGenerator;
|
|||||||
import org.springframework.security.crypto.keygen.StringKeyGenerator;
|
import org.springframework.security.crypto.keygen.StringKeyGenerator;
|
||||||
import org.springframework.web.util.HtmlUtils;
|
import org.springframework.web.util.HtmlUtils;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
import org.springframework.web.util.UriUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirect using an auto-submitting HTML form using the POST method. All query params
|
* Redirect using an auto-submitting HTML form using the POST method. All query params
|
||||||
@@ -83,8 +85,12 @@ public final class FormPostRedirectStrategy implements RedirectStrategy {
|
|||||||
|
|
||||||
final StringBuilder hiddenInputsHtmlBuilder = new StringBuilder();
|
final StringBuilder hiddenInputsHtmlBuilder = new StringBuilder();
|
||||||
for (final Entry<String, List<String>> entry : uriComponentsBuilder.build().getQueryParams().entrySet()) {
|
for (final Entry<String, List<String>> entry : uriComponentsBuilder.build().getQueryParams().entrySet()) {
|
||||||
final String name = entry.getKey();
|
final String name = UriUtils.decode(entry.getKey(), StandardCharsets.UTF_8);
|
||||||
for (final String value : entry.getValue()) {
|
for (final String raw : entry.getValue()) {
|
||||||
|
if (raw == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final String value = UriUtils.decode(raw, StandardCharsets.UTF_8);
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
final String hiddenInput = HIDDEN_INPUT_TEMPLATE
|
final String hiddenInput = HIDDEN_INPUT_TEMPLATE
|
||||||
.replace("{{name}}", HtmlUtils.htmlEscape(name))
|
.replace("{{name}}", HtmlUtils.htmlEscape(name))
|
||||||
|
|||||||
@@ -101,6 +101,19 @@ public class FormPostRedirectStrategyTests {
|
|||||||
assertThat(this.response).satisfies(hasScriptSrcNonce());
|
assertThat(this.response).satisfies(hasScriptSrcNonce());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gh-19136
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void absoluteUrlWithPercentEncodedQueryParamsRedirect() throws IOException {
|
||||||
|
this.redirectStrategy.sendRedirect(this.request, this.response, "https://example.com/cb?payload=a%2Bb%2Fc%3D");
|
||||||
|
assertThat(this.response.getStatus()).isEqualTo(HttpStatus.OK.value());
|
||||||
|
assertThat(this.response.getContentType()).isEqualTo(MediaType.TEXT_HTML_VALUE);
|
||||||
|
assertThat(this.response.getContentAsString()).contains("action=\"https://example.com/cb\"");
|
||||||
|
assertThat(this.response.getContentAsString())
|
||||||
|
.contains("<input name=\"payload\" type=\"hidden\" value=\"a+b/c=\" />");
|
||||||
|
assertThat(this.response).satisfies(hasScriptSrcNonce());
|
||||||
|
}
|
||||||
|
|
||||||
private ThrowingConsumer<MockHttpServletResponse> hasScriptSrcNonce() {
|
private ThrowingConsumer<MockHttpServletResponse> hasScriptSrcNonce() {
|
||||||
return (response) -> {
|
return (response) -> {
|
||||||
final String policyDirective = response.getHeader("Content-Security-Policy");
|
final String policyDirective = response.getHeader("Content-Security-Policy");
|
||||||
|
|||||||
Reference in New Issue
Block a user