Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter out invalid URI and HTTP method in the error message of no handler found for a REST request #3459

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions server/src/main/java/org/opensearch/rest/RestController.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
Expand Down Expand Up @@ -447,7 +448,9 @@ private void handleUnsupportedHttpMethod(
msg.append("Incorrect HTTP method for uri [").append(uri);
msg.append("] and method [").append(method).append("]");
} else {
msg.append(exception.getMessage());
// Not using the error message directly from 'exception.getMessage()' to avoid unescaped HTML special characters,
// in case false-positive cross site scripting vulnerability is detected by common security scanners.
msg.append("Unexpected HTTP method");
}
if (validMethodSet.isEmpty() == false) {
msg.append(", allowed: ").append(validMethodSet);
Expand Down Expand Up @@ -488,7 +491,14 @@ private void handleBadRequest(String uri, RestRequest.Method method, RestChannel
try (XContentBuilder builder = channel.newErrorBuilder()) {
builder.startObject();
{
builder.field("error", "no handler found for uri [" + uri + "] and method [" + method + "]");
try {
// Validate input URI to filter out HTML special characters in the error message,
// in case false-positive cross site scripting vulnerability is detected by common security scanners.
uri = new URI(uri).getPath();
builder.field("error", "no handler found for uri [" + uri + "] and method [" + method + "]");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, do you want to sanitize method as well?

Copy link
Collaborator Author

@tlfeng tlfeng Jun 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your review is so quick!
Sure, I can sanitize the error message for the HTTP method, although it may not necessary, since there is no code security scanners have an alarm on that. 😄
I will update the code then.

Note:
After taking a look at the code, the error message of invalid HTTP method is directly obtained from the
https://github.com/opensearch-project/OpenSearch/blob/2.0.0/server/src/main/java/org/opensearch/rest/RestController.java#L450
https://github.com/opensearch-project/OpenSearch/blob/2.0.0/modules/transport-netty4/src/main/java/org/opensearch/http/netty4/Netty4HttpRequest.java#L148

Copy link
Collaborator Author

@tlfeng tlfeng Jun 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in the new commit 863e272 . 👍

} catch (Exception e) {
builder.field("error", "invalid uri has been requested");
}
}
builder.endObject();
channel.sendResponse(new BytesRestResponse(BAD_REQUEST, builder));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,15 @@ public void testFaviconWithWrongHttpMethod() {
assertThat(channel.getRestResponse().getHeaders().get("Allow"), hasItem(equalTo(RestRequest.Method.GET.toString())));
}

public void testHandleBadRequestWithHtmlSpecialCharsInUri() {
final FakeRestRequest fakeRestRequest = new FakeRestRequest.Builder(NamedXContentRegistry.EMPTY).withPath(
"/<script>alert('xss');alert(\"&#x6A&#x61&#x76&#x61\");</script>"
).build();
final AssertingChannel channel = new AssertingChannel(fakeRestRequest, true, RestStatus.BAD_REQUEST);
restController.dispatchRequest(fakeRestRequest, channel, client.threadPool().getThreadContext());
assertThat(channel.getRestResponse().content().utf8ToString(), containsString("invalid uri has been requested"));
}

public void testDispatchUnsupportedHttpMethod() {
final boolean hasContent = randomBoolean();
final RestRequest request = RestRequest.request(xContentRegistry(), new HttpRequest() {
Expand Down Expand Up @@ -623,6 +632,10 @@ public Exception getInboundException() {
assertTrue(channel.getSendResponseCalled());
assertThat(channel.getRestResponse().getHeaders().containsKey("Allow"), equalTo(true));
assertThat(channel.getRestResponse().getHeaders().get("Allow"), hasItem(equalTo(RestRequest.Method.GET.toString())));
assertThat(
channel.getRestResponse().content().utf8ToString(),
equalTo("{\"error\":\"Unexpected HTTP method, allowed: [GET]\",\"status\":405}")
);
}

private static final class TestHttpServerTransport extends AbstractLifecycleComponent implements HttpServerTransport {
Expand Down