jetty / jetty.project

Eclipse Jetty® - Web Container & Clients - supports HTTP/2, HTTP/1.1, HTTP/1.0, websocket, servlets, and more
https://eclipse.dev/jetty
Other
3.86k stars 1.91k forks source link

Issue with URL Parsing in Jetty HttpURI Class Not Complying with RFC Standards #12473

Open zer0yu opened 1 week ago

zer0yu commented 1 week ago

Jetty version(s)

Jetty Environment

Java version/vendor (use: java -version)

java version "21.0.3" 2024-04-16 LTS
Java(TM) SE Runtime Environment (build 21.0.3+7-LTS-235)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.3+7-LTS-235, mixed mode)

OS type/version

Description

I would like to report an issue related to inconsistent URL parsing in Jetty's org.eclipse.jetty.http.HttpURI class, which may lead to potential security risks.

When parsing certain malformed URLs containing invalid IPv6 literals and port numbers, Jetty's parsing behavior differs from standard parsers and its own newer versions. This inconsistency can cause unexpected results and may introduce vulnerabilities such as Server-Side Request Forgery (SSRF) and access control bypasses.

How to reproduce?

  1. Test Payloads and Observed Behavior:

    Payload Browser (Chrome) Rust Python urllib3 Jetty 12.0.10 Jetty 12.0.12
    http://[vulndetector.com]:99999 Invalid URL Invalid IPv6 address Failed to parse Port: 99999 Error: Bad authority
    http://vulndetector.com:99999/ Invalid URL Invalid port number Failed to parse Port: 99999 Port: 99999
    http://localhost:-1 Invalid URL Invalid port number Failed to parse Error: Exception (e.g., !hex 45) Host: localhost:-1
    Port: -1
    http://[localhost:-1] Invalid URL Invalid IPv6 address Failed to parse Error: Index out of bounds exception Error: Bad authority
  2. Reproduction Steps:

    • Code Sample:

      import org.eclipse.jetty.http.HttpURI;
      
      public class TestHttpURI {
       public static void main(String[] args) {
           String[] testUrls = {
               "http://[vulndetector.com]:99999",
               "http://vulndetector.com:99999/",
               "http://localhost:-1",
               "http://[localhost:-1]"
           };
      
           for (String url : testUrls) {
               try {
                   HttpURI httpUri = new HttpURI(url);
                   System.out.println("URL: " + url);
                   System.out.println("Host: " + httpUri.getHost());
                   System.out.println("Port: " + httpUri.getPort());
                   System.out.println("-----------------------------");
               } catch (Exception e) {
                   System.out.println("URL: " + url);
                   System.out.println("Error: " + e.getMessage());
                   System.out.println("-----------------------------");
               }
           }
       }
      }
    • Execution:

      • Compile the code:
      javac -cp /path/to/jetty-http-12.0.10.jar TestHttpURI.java
      • Run the code with Jetty 12.0.10:
      java -cp .:/path/to/jetty-http-12.0.10.jar TestHttpURI
      • Run the code with Jetty 12.0.12:
      java -cp .:/path/to/jetty-http-12.0.12.jar TestHttpURI
  3. Expected Behavior:

    • The parser should strictly adhere to RFC 3986 and reject invalid URLs.
    • Invalid IPv6 literals and invalid port numbers should result in clear exceptions or error messages.
  4. Observed Behavior:

    • Jetty 12.0.10:

      • Accepts invalid URLs and extracts port numbers even when they are out of the valid range.
      • May produce unexpected results or exceptions.
    • Jetty 12.0.12:

      • Introduces stricter validation, rejecting malformed URLs with errors like "Bad authority".
      • However, inconsistencies still exist compared to other standard parsers.

Additional Information:

Recommendation: