Skip to content

DocumentParser: XML body parsed without XXE hardening (CWE-611) #724

Description

@elarasu

Summary

com.koushikdutta.async.parser.DocumentParser and the response side of com.koushikdutta.async.http.body.DocumentBody parse HTTP response bodies as XML using a DocumentBuilderFactory with no XML External Entity (XXE) hardening. Because this parser is the default `AsyncParser` returned for `text/xml` responses, any client app fetching XML from an untrusted (or compromised) server is exposed to XXE — file disclosure, SSRF, billion-laughs DoS.

Location

`AndroidAsync/src/com/koushikdutta/async/parser/DocumentParser.java:23`

```java
public class DocumentParser implements AsyncParser {
@OverRide
public Future parse(DataEmitter emitter) {
return new ByteBufferListParser().parse(emitter)
.thenConvert(from -> DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteBufferListInputStream(from)));
}
...
@OverRide public String getMime() { return "text/xml"; }
}
```

No hardening is applied to the `DocumentBuilderFactory`:

  • No `setFeature("http://apache.org/xml/features/disallow-doctype-decl\", true)`
  • No `setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true)`
  • No disabling of external general/parameter entities or external DTD loading
  • `setExpandEntityReferences` left at default (true)

Impact

An Android (or JVM) application using AndroidAsync to fetch XML over HTTP:

```java
AsyncHttpClient.getDefaultInstance().executeDocument(new AsyncHttpGet(url), callback);
```

…can be served a malicious payload by any HTTP origin it talks to:

```xml

]>
&xxe;
```

On Android, the result of resolving such an entity is typically reflected back into the app via the parsed `Document` and may end up logged, displayed, or proxied. On the JVM the same primitive enables SSRF and file disclosure against the app's local filesystem.

Suggested fix

Apply the OWASP XXE Prevention Cheat Sheet hardening at factory construction. Each `setFeature` should be try/catched and tolerated if the underlying JAXP provider doesn't support it (so the library remains pluggable):

```java
private static DocumentBuilderFactory hardenedFactory() {
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
try { f.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); } catch (ParserConfigurationException ignored) {}
try { f.setFeature("http://apache.org/xml/features/disallow-doctype-decl\", true); } catch (ParserConfigurationException ignored) {}
try { f.setFeature("http://xml.org/sax/features/external-general-entities\", false); } catch (ParserConfigurationException ignored) {}
try { f.setFeature("http://xml.org/sax/features/external-parameter-entities\", false); } catch (ParserConfigurationException ignored) {}
try { f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd\", false); } catch (ParserConfigurationException ignored) {}
f.setXIncludeAware(false);
f.setExpandEntityReferences(false);
return f;
}
```

If applications need to accept DOCTYPEs deliberately, expose a builder option rather than defaulting to permissive parsing.

How found

SAST sweep over the top-100 starred Java repos on GitHub.

References

  • CWE-611: Improper Restriction of XML External Entity Reference
  • OWASP XXE Prevention Cheat Sheet — Java DocumentBuilderFactory section

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions