Sanitize inputs in default reactive HTML error view
This commit uses HTML escaping to sanitize error inputs that are displayed in the default reactive HTML error view. Fixes gh-11582
This commit is contained in:
parent
381d759ef1
commit
1f26a0314c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2017 the original author or authors.
|
* Copyright 2012-2018 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.
|
||||||
|
@ -38,6 +38,7 @@ import org.springframework.web.reactive.function.server.ServerRequest;
|
||||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||||
import org.springframework.web.reactive.result.view.ViewResolver;
|
import org.springframework.web.reactive.result.view.ViewResolver;
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
import org.springframework.web.util.HtmlUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for {@link ErrorWebExceptionHandler} implementations.
|
* Abstract base class for {@link ErrorWebExceptionHandler} implementations.
|
||||||
|
@ -191,9 +192,11 @@ public abstract class AbstractErrorWebExceptionHandler
|
||||||
.append("<p>This application has no configured error view, so you are seeing this as a fallback.</p>")
|
.append("<p>This application has no configured error view, so you are seeing this as a fallback.</p>")
|
||||||
.append("<div id='created'>").append(timestamp.toString())
|
.append("<div id='created'>").append(timestamp.toString())
|
||||||
.append("</div>").append("<div>There was an unexpected error (type=")
|
.append("</div>").append("<div>There was an unexpected error (type=")
|
||||||
.append(error.get("error")).append(", status=")
|
.append(HtmlUtils.htmlEscape(error.get("error").toString())).append(", status=")
|
||||||
.append(error.get("status")).append(").</div>").append("<div>")
|
.append(HtmlUtils.htmlEscape(error.get("status").toString()))
|
||||||
.append(error.get("message")).append("</div>").append("</body></html>");
|
.append(").</div>").append("<div>")
|
||||||
|
.append(HtmlUtils.htmlEscape(error.get("message").toString()))
|
||||||
|
.append("</div>").append("</body></html>");
|
||||||
return responseBody.syncBody(builder.toString());
|
return responseBody.syncBody(builder.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,6 +220,27 @@ public class DefaultErrorWebExceptionHandlerIntegrationTests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void escapeHtmlInDefaultErrorView() throws Exception {
|
||||||
|
this.contextRunner
|
||||||
|
.withPropertyValues("spring.mustache.prefix=classpath:/unknown/")
|
||||||
|
.run((context) -> {
|
||||||
|
WebTestClient client = WebTestClient.bindToApplicationContext(context)
|
||||||
|
.build();
|
||||||
|
String body = client.get().uri("/html").accept(MediaType.TEXT_HTML)
|
||||||
|
.exchange().expectStatus()
|
||||||
|
.isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR).expectHeader()
|
||||||
|
.contentType(MediaType.TEXT_HTML).expectBody(String.class)
|
||||||
|
.returnResult().getResponseBody();
|
||||||
|
assertThat(body).contains("Whitelabel Error Page")
|
||||||
|
.doesNotContain("<script>")
|
||||||
|
.contains("<script>");
|
||||||
|
this.output.expect(
|
||||||
|
allOf(containsString("Failed to handle request [GET /html]"),
|
||||||
|
containsString("IllegalStateException")));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void responseCommitted() throws Exception {
|
public void responseCommitted() throws Exception {
|
||||||
this.contextRunner.run((context) -> {
|
this.contextRunner.run((context) -> {
|
||||||
|
@ -253,6 +274,11 @@ public class DefaultErrorWebExceptionHandlerIntegrationTests {
|
||||||
Mono.error(new IllegalStateException("already committed!")));
|
Mono.error(new IllegalStateException("already committed!")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/html")
|
||||||
|
public String htmlEscape() {
|
||||||
|
throw new IllegalStateException("<script>");
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping(path = "/bind", produces = "application/json")
|
@PostMapping(path = "/bind", produces = "application/json")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String bodyValidation(@Valid @RequestBody DummyBody body) {
|
public String bodyValidation(@Valid @RequestBody DummyBody body) {
|
||||||
|
|
Loading…
Reference in New Issue