Skip to content

Commit 2bfe8b3

Browse files
author
Tianli Feng
authored
Filter out invalid URI and HTTP method in the error message of no handler found for a REST request (#3459)
Filter out invalid URI and HTTP method of a error message, which shown when there is no handler found for a REST request sent by user, so that HTML special characters <>&"' will not shown in the error message. The error message is return as mine-type `application/json`, which can't contain active (script) content, so it's not a vulnerability. Besides, no browsers are going to render as html when the mine-type is that. While the common security scanners will raise a false-positive alarm for having HTML tags in the response without escaping the HTML special characters, so the solution only aims to satisfy the code security scanners. Signed-off-by: Tianli Feng <[email protected]>
1 parent 1ceff28 commit 2bfe8b3

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

server/src/main/java/org/opensearch/rest/RestController.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import java.io.ByteArrayOutputStream;
5757
import java.io.IOException;
5858
import java.io.InputStream;
59+
import java.net.URI;
5960
import java.util.HashMap;
6061
import java.util.HashSet;
6162
import java.util.Iterator;
@@ -447,7 +448,9 @@ private void handleUnsupportedHttpMethod(
447448
msg.append("Incorrect HTTP method for uri [").append(uri);
448449
msg.append("] and method [").append(method).append("]");
449450
} else {
450-
msg.append(exception.getMessage());
451+
// Not using the error message directly from 'exception.getMessage()' to avoid unescaped HTML special characters,
452+
// in case false-positive cross site scripting vulnerability is detected by common security scanners.
453+
msg.append("Unexpected HTTP method");
451454
}
452455
if (validMethodSet.isEmpty() == false) {
453456
msg.append(", allowed: ").append(validMethodSet);
@@ -488,7 +491,14 @@ private void handleBadRequest(String uri, RestRequest.Method method, RestChannel
488491
try (XContentBuilder builder = channel.newErrorBuilder()) {
489492
builder.startObject();
490493
{
491-
builder.field("error", "no handler found for uri [" + uri + "] and method [" + method + "]");
494+
try {
495+
// Validate input URI to filter out HTML special characters in the error message,
496+
// in case false-positive cross site scripting vulnerability is detected by common security scanners.
497+
uri = new URI(uri).getPath();
498+
builder.field("error", "no handler found for uri [" + uri + "] and method [" + method + "]");
499+
} catch (Exception e) {
500+
builder.field("error", "invalid uri has been requested");
501+
}
492502
}
493503
builder.endObject();
494504
channel.sendResponse(new BytesRestResponse(BAD_REQUEST, builder));

server/src/test/java/org/opensearch/rest/RestControllerTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,15 @@ public void testFaviconWithWrongHttpMethod() {
553553
assertThat(channel.getRestResponse().getHeaders().get("Allow"), hasItem(equalTo(RestRequest.Method.GET.toString())));
554554
}
555555

556+
public void testHandleBadRequestWithHtmlSpecialCharsInUri() {
557+
final FakeRestRequest fakeRestRequest = new FakeRestRequest.Builder(NamedXContentRegistry.EMPTY).withPath(
558+
"/<script>alert('xss');alert(\"&#x6A&#x61&#x76&#x61\");</script>"
559+
).build();
560+
final AssertingChannel channel = new AssertingChannel(fakeRestRequest, true, RestStatus.BAD_REQUEST);
561+
restController.dispatchRequest(fakeRestRequest, channel, client.threadPool().getThreadContext());
562+
assertThat(channel.getRestResponse().content().utf8ToString(), containsString("invalid uri has been requested"));
563+
}
564+
556565
public void testDispatchUnsupportedHttpMethod() {
557566
final boolean hasContent = randomBoolean();
558567
final RestRequest request = RestRequest.request(xContentRegistry(), new HttpRequest() {
@@ -623,6 +632,10 @@ public Exception getInboundException() {
623632
assertTrue(channel.getSendResponseCalled());
624633
assertThat(channel.getRestResponse().getHeaders().containsKey("Allow"), equalTo(true));
625634
assertThat(channel.getRestResponse().getHeaders().get("Allow"), hasItem(equalTo(RestRequest.Method.GET.toString())));
635+
assertThat(
636+
channel.getRestResponse().content().utf8ToString(),
637+
equalTo("{\"error\":\"Unexpected HTTP method, allowed: [GET]\",\"status\":405}")
638+
);
626639
}
627640

628641
private static final class TestHttpServerTransport extends AbstractLifecycleComponent implements HttpServerTransport {

0 commit comments

Comments
 (0)