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 <ftianli@amazon.com>
This commit is contained in:
parent
1ceff286a0
commit
2bfe8b31af
|
@ -56,6 +56,7 @@ import org.opensearch.usage.UsageService;
|
|||
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;
|
||||
|
@ -447,7 +448,9 @@ public class RestController implements HttpServerTransport.Dispatcher {
|
|||
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);
|
||||
|
@ -488,7 +491,14 @@ public class RestController implements HttpServerTransport.Dispatcher {
|
|||
try (XContentBuilder builder = channel.newErrorBuilder()) {
|
||||
builder.startObject();
|
||||
{
|
||||
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 + "]");
|
||||
} catch (Exception e) {
|
||||
builder.field("error", "invalid uri has been requested");
|
||||
}
|
||||
}
|
||||
builder.endObject();
|
||||
channel.sendResponse(new BytesRestResponse(BAD_REQUEST, builder));
|
||||
|
|
|
@ -553,6 +553,15 @@ public class RestControllerTests extends OpenSearchTestCase {
|
|||
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(\"java\");</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() {
|
||||
|
@ -623,6 +632,10 @@ public class RestControllerTests extends OpenSearchTestCase {
|
|||
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 {
|
||||
|
|
Loading…
Reference in New Issue