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

URIUtil works in combination with UriCompliance #11453

Closed
VnzBzk opened this issue Feb 27, 2024 · 7 comments
Closed

URIUtil works in combination with UriCompliance #11453

VnzBzk opened this issue Feb 27, 2024 · 7 comments
Labels

Comments

@VnzBzk
Copy link

VnzBzk commented Feb 27, 2024

Jetty version(s)
12.0.6

Jetty Environment
ee8

Java version/vendor
openjdk version "17.0.8.1" 2023-08-24 LTS
OpenJDK Runtime Environment (build 17.0.8.1+1-LTS)
OpenJDK 64-Bit Server VM (build 17.0.8.1+1-LTS, mixed mode, sharing)

OS type/version
Description: Ubuntu 22.04.4 LTS
Release: 22.04
Codename: jammy

Question
Jetty returns HTTP ERROR 400 Invalid request although we configured Jetty with following HttpConfiguration:

private static void manageHttpConfig(Server server, int port) {
    HttpConfiguration httpConfig = new HttpConfiguration();
    httpConfig.setSendServerVersion(false);
    httpConfig.setUriCompliance(UriCompliance.from(Set.of(
            UriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR)));

When requesting for a specific context like this http://localhost:8080/energy/values/test%2Ftest the %2F wont lead to the BadMessageException in the HttpConnection (this works) but it will be converted back to a / in the URIUtil.decodePath. This leads to a wrong pathInContext within the Request of the Context. Is this a bug or have i missed a specific Configuration?

The Jetty log looks like this:

DEBUG org.eclipse.jetty.ee8.nested.HttpChannel      - action DISPATCH HttpChannel@4e34ce4a{s=HttpChannelState@3f163f2c{s=HANDLING rs=BLOCKING os=OPEN is=IDLE awp=false se=false i=true al=0},r=3,c=false/false,a=HANDLING,uri=http://localhost:8080/energy/values/test%2Ftest,age=0}

DEBUG org.eclipse.jetty.ee8.nested.ContextHandler   - REQUEST GET /energy/values/test/test ?null on HttpChannel@4e34ce4a{s=HttpChannelState@3f163f2c{s=HANDLING rs=BLOCKING os=OPEN is=IDLE awp=false se=false i=true al=0},r=3,c=false/false,a=HANDLING,uri=http://localhost:8080/energy/values/test%2Ftest,age=0}
@joakime
Copy link
Contributor

joakime commented Feb 27, 2024

The configuration ...

    httpConfig.setUriCompliance(UriCompliance.from(Set.of(
            UriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR)));

Means you are allowing AMBIGUOUS_PATH_SEPARATOR which will allow the %2F through the HttParser and handling is allowed to begin.

There's a testcase present in PR #11454 that shows this is working, at least for jetty-core.

@gregw
Copy link
Contributor

gregw commented Feb 27, 2024

@VnzBzk The spec for ee8 had not considered how characters like %2F can be confusing. The methods like getServletPath and getPathInfo are documented to return a decoded string, so the %2F is decoded to "/". This can be confusing / ambiguous, so by default, Jetty does not allow such requests into the servlet container as they may bypass security constraints or trip up the application in some other way. By configuring UriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR you allow the request into the container, but we still cannot do anything about the ambiguous decoding.

If you wish to handle such URIs then you are best to use the getRequestURI() method to obtain the encoded path and then you can do your own handling that is able to deal with the %2F correctly.

@joakime
Copy link
Contributor

joakime commented Feb 28, 2024

@VnzBzk also note that using %2F in the path section of a URI is no longer possible in Servlet 6, you should migrate the usage of %2F to the query section.

See Servlet 6 changes around URI path (encoding / decoding / normalization / equivalence / etc):

This updated URI path behavior is even in the Servlet 6 TCK.
Many Servlet implementations provide non-standard configuration to bypass these rules, but the behavior is different in each implementation.
Most libraries that depend on the Servlet spec (spring / jersey / etc) do not recommend using these non-standard configurations.

@joakime
Copy link
Contributor

joakime commented Feb 28, 2024

For others that find this issue in the future, here's the Servlet 6 Spec documentation.

https://github.com/jakartaee/servlet/blob/6.0.0-RELEASE/spec/src/main/asciidoc/servlet-spec-body.adoc#352-uri-path-canonicalization

See 3.5.2. URI Path Canonicalization and point 10 in that section in particular for all of the various types of URI paths that can trigger the Servlet 6 rules mentioned in this issue.

@janbartel
Copy link
Contributor

Looks like the question has been addressed, so I'll close this issue.

@janitza-bjag
Copy link

janitza-bjag commented Mar 12, 2024

We have some servlets with spec 4 running with Jetty 10.0.12 where "%2F" in path mapping works as expected ... means that rest/vari%2Fable/ in the path mapping results in "vari/able" for variable type

@Path ("rest/{type}") public Response getValue(@PathParam ("type") String type)

With Jetty 10.0.15 this doesn't work anymore

@joakime
Copy link
Contributor

joakime commented Mar 12, 2024

@janitza-bjag Jetty versions 11 and older are now at End of Community Support.

See:

Also note that your versions 10.0.12 and 10.0.15 are subject to several security advisories.

Finally, the %2F was always ambiguous and not able to be properly supported by the Servlet spec (due to decisions long long ago, back in the HTTP/0.9 era, with regards to encoding / decoding of paths and the other APIs that require a stable and reproducible path).

It wasn't until Servlet 6.0 where the ambiguous nature of that encoded path separator was codified as not supported, and implementations must return 400 Bad Request when it receives a request path with an encoded %2F.

Note: there are MANY things that can appear in the path portion of a URL/URI that can cause problems in the Servlet spec, the encoded %2F is just one of them, see the updated Servlet spec about "Rejecting Suspicious Sequences" to get a feel for the kinds of request URL/URIs that have always caused problems with the Servlet spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants