-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Error 400 - Ambiguous URI Empty Segment #11298
Comments
What is your URI? |
@Justvuur It means your URI has an empty segment ( You can set the URI compliance mode in the
|
If any vaiolation of UriCompliance exists at entry point of ServletContextRequest , Jetty12 using Servlet returns 400 Bad Request. If you need shorthand workaround, make EmptySegmentHandler and make it handle before ServletContextHandler public class UriComplianceCheckHandler extends Handler.Wrapper {
public UriComplianceCheckHandler(Handler handler) {
super(handler);
}
@Override
public boolean handle(Request request, Response response, Callback callback) throws Exception {
if (request.getHttpURI().hasViolations()) {
return super.handle(rewriteRequest(request), response, callback);
} else {
return super.handle(request, response, callback);
}
}
Request rewriteRequest(Request request) {
log.warn("There are HttpURI Violation exists. HttpURI:{}. Violations:{}", request.getHttpURI(),
request.getHttpURI().getViolations());
if (request.getHttpURI().hasViolation(UriCompliance.Violation.AMBIGUOUS_EMPTY_SEGMENT)) {
HttpURI rewrite = rewriteHttpURL(request);
return Request.serveAs(request, rewrite);
}
return request;
}
private HttpURI rewriteHttpURL(Request base) {
String param = base.getHttpURI().getParam();
String query = base.getHttpURI().getQuery();
List<String> segments = Arrays
.stream(base.getHttpURI().getPath().split("\\/"))
.filter(v -> !v.isEmpty())
.toList();
String newPath = "/" + StringUtils.join(segments, "/");
return HttpURI.build(base.getHttpURI(), newPath, param, query).asImmutable();
}
} |
Ok, I managed to get it working but using Any ideas why? |
If you see To address this problem you have to address what is going on with your HTTP Client. Jetty does not "clean up" these kinds of URIs as there are some libraries that rely on this ambiguity (esp security frameworks). |
I might have similar problem: Jetty Version Jetty Environment Java Version My request look like this: http://localhost//something.js and I'm also getting 400: Ambiguous URI empty segment I have set UriCompliance.LEGACY but it doesn't work for me any chance how to get it working? Thanks! |
@salacr Are you sure you have set LEGACY mode? Note that there is also the |
@gregw I have unfortunately in ServletContextRequest.java And it still returns the
I will check the CompactPathRule then thanks. |
Unfortunately, even when CompactPathRule and the URI are rewritten the violations are already set so I'm still getting same error. Any other advice will be highly apriciated |
Same here, I changed it to LEGACY in jetty.xml , but when call getSerlvetPath() , it still throws 400 because AmbiguousURI was returned |
…tions before parsing the new path. Fixes: #11298
@chiqiu as pointed out in the Servlet spec, those paths are ambiguous and lead to all kinds of bugs in the servlet spec. The AmbiguousURI class properly throws an exception in the case of .getServletPath() and .getPathInfo() as it is not possible to support an ambiguous path with those servlet methods. (there are similar failures for ambiguous paths found in other places in the servlet spec as well. eg: getRequestDispatcher and sendRedirect APIs) Just using LEGACY without fixing the paths before sending them into the Servlet API will always result in these kinds of issues. The changes in PR #12306 should help with most, but not all, ambiguous path related fixes that the CompactPathRule is capable of addressing. (other ambiguous path situations need to be addressed with custom code that is specific to your webapp). |
That TODO and that section of the code is all about if ambiguous URIs will be returned from the servlet API I've tested that we do act correctly with the following test added to org.eclipse.jetty.ee10.servlet.ComplianceViolations2616Test @Test
public void testAmbiguousSlash() throws Exception
{
String request = """
GET /dump/foo//bar HTTP/1.1\r
Host: local\r
Connection: close\r
\r
""";
String response = connector.getResponse(request);
assertThat(response, containsString("HTTP/1.1 400 Bad"));
connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setUriCompliance(UriCompliance.RFC3986.with("test", UriCompliance.Violation.AMBIGUOUS_EMPTY_SEGMENT));
response = connector.getResponse(request);
assertThat(response, containsString("HTTP/1.1 200 OK"));
} |
I also tested with servletAPI calls in the servlet and used: @Test
public void testAmbiguousSlash() throws Exception
{
String request = """
GET /dump/foo//bar HTTP/1.1\r
Host: local\r
Connection: close\r
\r
""";
String response = connector.getResponse(request);
assertThat(response, containsString("HTTP/1.1 400 Bad"));
connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setUriCompliance(UriCompliance.RFC3986.with("test", UriCompliance.Violation.AMBIGUOUS_EMPTY_SEGMENT));
server.getContainedBeans(ServletHandler.class).stream().findFirst().get().setDecodeAmbiguousURIs(true);
response = connector.getResponse(request);
assertThat(response, containsString("HTTP/1.1 200 OK"));
assertThat(response, containsString("GET /dump/foo//bar"));
} |
Thanks a lot @gregw that made it working. We will start process of migration to valid urls but it will take quite a time :/ so in meantime this will help a lot |
Jetty Version
12.0.3
Jetty Environment
ee8
Java Version
JavaSE-17
Question
I just migrated from Jetty 10.0.15 to 12.0.3 and I keep getting the following error:
URI: /badURI
STATUS: 400
MESSAGE: Ambiguous URI empty segment
CAUSED BY: org.eclipse.jetty.http.BadMessageException: 400: Ambiguous URI empty segment
Any ideas what could be causing this?
The text was updated successfully, but these errors were encountered: