-
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
Jetty 12: 400: Ambiguous URI path encoding for path <%=FOO%>~1 (encoded: %3C%25%3DFOO%25%3E%7E1) #11890
Comments
See #11448 (comment) for a workaround, although proceed with caution as it's not spec compliant. |
Thanks for the pointer. If we cannot pass '/' as part of the URI over HTTP any more, we can cancel Gerrit Code Review project.
This is a usual request to delete git branch with the name: I tried to set It doesn't seem to be respected. For one I see, that the violation ./jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java switch (encodedValue)
{
case 0:
// Byte 0 cannot be present in a UTF-8 sequence in any position
// other than as the NUL ASCII byte which we do not wish to allow.
throw new IllegalArgumentException("Illegal character in path");
case '/':
addViolation(Violation.AMBIGUOUS_PATH_SEPARATOR);
break;
case '%':
addViolation(Violation.AMBIGUOUS_PATH_ENCODING);
break;
default:
if (encodedValue < __suspiciousPathCharacters.length && __suspiciousPathCharacters[encodedValue])
addViolation(Violation.SUSPICIOUS_PATH_CHARACTERS);
break;
} with this stack trace:
For another, the bad request exception (Status 400) is unconditionally thrown in ./jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/internal/HttpConnection.java String badMessage = UriCompliance.checkUriCompliance(compliance, _uri, getHttpChannel().getComplianceViolationListener());
if (badMessage != null)
throw new BadMessageException(badMessage); with this stack trace:
What am I missing? In case it helps for analysis, here is the complete debug log. |
You cannot pass a ambiguous But you can pass that encoded reference as part of the query section of a URI. |
UriCompliance.NO_VIOLATION is a mode that will not allow any violation listed in UriCompliance.Violation. Use this instead. httpConfig.setUriCompliance(UriCompliance.from(Set.of(
UriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR,
UriCompliance.Violation.AMBIGUOUS_PATH_ENCODING))); That says you are allowing AMBIGUOUS_PATH_SEPARATOR and AMBIGUOUS_PATH_ENCODING through. This answer is pretty much from #11448 (comment) and also linked example code.
That's where the violation is detected, and noted, it being enforced is elsewhere in the code.
That's one of the enforcement locations (not the only one), and will honor configuration present in
Note that you cannot pass AMBIGUOUS path segments, meaning the In Servlet terms, a url-pattern of |
Thanks, I misread the javadoc. It works now as expected.
But then the API would be ambiguous:
Would this request delete project (aka git repository) with the name: |
This is the nature of HTTP, and the URI specs. The URI spec in your case should have used a forbidden character (to git) as a separator, not a Example: both
|
Note that in this case %25 encode is actually allowed by the Servlet Spec, but it is Jetty that is being a bit more cautious. See https://jakarta.ee/specifications/servlet/6.0/jakarta-servlet-spec-6.0#uri-path-canonicalization Also, it is possible to build a compliance mode based on other compliance modes, rather than specifically list all of the Violations you wish to allow. In this case, it would probably be simplest to use
|
Thanks for clarifying. I also noticed, that to activate the legacy mode for URL compliance is harder to achieve as is probably should be: /**
* Allow ambiguous path separator and ambiguous path encoding violation.
*
* <p><em>WARNING</em> this is not recommended. This is a violation of the Servlet 6 spec rules.
*
* @param configuration HTTP configuration instance
*/
private static void customizeUriCompliance(HttpConfiguration configuration) {
configuration.setUriCompliance(UriCompliance.LEGACY);
}
/**
* Bypass Servlet 6 spec rules on ambiguous URIs.
*
* <p><em>WARNING</em> this is not recommended. This is a violation of the Servlet 6 spec rules.
*
* @param httpd Jetty server instance
* @see <a href="https://github.com/jakartaee/servlet/issues/18">Servlet 6 changes to
* getRequestURI / getRequestContextPath / getServletPath / getPathInfo</a>
*/
private static void bypassServlet6UriRules(Server httpd) {
httpd
.getContainedBeans(ServletHandler.class)
.forEach(handler -> handler.setDecodeAmbiguousURIs(true));
} If I already asking the HTTP configuration to set Uri Compliance to Can't the latter setting be induced from the former to simplify the client code? See also the whole changes in |
The The They are different specs you are controlling. Also keep in mind that if you use anything else in Jakarta EE10, such as Jakarta REST (eg: jaxrs), or Jakarta Pages (eg: JSP), (and many more) you'll have to find the levers for those Spec as well to enable Ambiguous URIs, as all specs in Jakarta are now following the up to date URI spec rules and are not allowing ambiguous path segments for various reasons (a combination of following the servlet spec and various security issues that arise from allowing it in their specs). |
@joakime Thanks, makes sense. |
I have a java app deployed on appengine using gcloud. Please advise. I do not have a main (or a Main) in my app. I am using jetty 12.0.3 in my pom.xml |
This commit implements the changes for KIP-1032. This updates Kafka to Jakarta specs, JavaEE 10 and Jetty 12. The changes here primarily effect Kafka Connect and MM2. Todo/Notes: 1) I bumped the connect modules to JDK 17 but I also had to bump a couple other things that had a dependency on conect. The tools project depends on connect so that had to be bumped, and streams depends on tools so that needed to be bumped. This means we may need to separate some things if we don't want to enforce JDK 17 on streams. 2) There is an issue with a test in DedicatedMirrorIntegrationTest that I had to change for now that involves escaping characters and not quite sure what to do about it yet. The cause is the Servlet 6 spec changing what is allowed in the path. See: Jetty 12: 400: Ambiguous URI path encoding for path <%=FOO%>~1 (encoded: %3C%25%3DFOO%25%3E%7E1) jetty/jetty.project#11890 3) I had to configure the idle timeout in Jetty requests to match our request timeout so tests didn't fail. This was needed to fix the ConnectWorkerIntegrationTest#testPollTimeoutExpiry() test Testing is being done by just using the existing tests for Connect and MM2 which should be sufficient. Reviewers: Greg Harris <[email protected]>, David Arthur <[email protected]>, Chia-Ping Tsai <[email protected]>
Jetty version(s)
Jetty 12.0.10
Jetty Environment
ee10
Java version/vendor
(use: java -version)
JDK21
OS type/version
Linux
Description
We are migrating Gerrit Code Review project to Jetty 12.
One test is failing with encoding problem.
This is the related Gerrit change.
See also this SO question.
gerrit/javatests/com/google/gerrit/acceptance/rest/change/ChangeIdIT.java
where
fromDecoded: %3C%25%3DFOO%25%3E%7E1
.And the whole endpoint is
/changes/%3C%25%3DFOO%25%3E%7E1/detail
.Starting from Jetty 12 this path is rejected with this exception:
So that the test is failing with HTTP status mismatch:
There are even more failures with the same encoding pattern, so that I'm posting it here, instead of filing new issue:
Also for this project name, where trailing slash was encoded:
com.google.gerrit.acceptance.rest.project.CreateChangeIT_matchingProjectWithTrailingSlashIsAccepted_project%2F
is failing with the same exception:
Also deleting of this git branch is failing now in REST endpoint, where
/
was encoded:/projects/hxkePMGw/branches/refs%2Fheads%2Ftest
.How to reproduce?
Clone gerrit code review project, apply this pending CL
Fetch patch set 11 of this change:
and run:
The text was updated successfully, but these errors were encountered: