diff --git a/src/main/java/org/apache/commons/xml/XmlFactories.java b/src/main/java/org/apache/commons/xml/XmlFactories.java index a01b914..b070c3e 100644 --- a/src/main/java/org/apache/commons/xml/XmlFactories.java +++ b/src/main/java/org/apache/commons/xml/XmlFactories.java @@ -38,10 +38,14 @@ *
These guarantees are defined on OpenJDK 8 or later (and JDK distributions built from it). No version of Android supports + * {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING}, so on Android (API level 19 or later) the hardening is applied as best-effort without a guarantee, + * tested as complete starting with API level 33; see the threat model's "Assumptions about the environment".
+ * *The guarantees hold whether or not the caller opts into DTD validation * ({@link javax.xml.parsers.DocumentBuilderFactory#setValidating(boolean) setValidating(true)}) or attaches a compiled XSD via * {@link javax.xml.parsers.DocumentBuilderFactory#setSchema(javax.xml.validation.Schema) setSchema}: every external resource the validation would otherwise diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index f16249c..f79eae8 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -65,6 +65,18 @@ it resolves to empty content, so the parse continues without it (see Configuration below). +### Supported runtimes + +The library requires OpenJDK 8 or later (or a JDK distribution built from it), or Android API level 19 or later. + +The security guarantees are defined only on the OpenJDK family +(see the [Threat Model](threat_model.html)). +No version of Android supports `FEATURE_SECURE_PROCESSING` +(so states [Android's own documentation](https://developer.android.com/reference/javax/xml/parsers/DocumentBuilderFactory#setFeature%28java.lang.String,%20boolean%29)), +so the library secures the platform's parsers as best-effort. +Android's `XmlPullParser` API is not supported: +it is not a JAXP API. + ### Supported implementations Out of the box the library recognizes the stock JDK JAXP implementations, Apache Xerces 2.x, Woodstox, and Saxon-HE. If diff --git a/src/site/markdown/threat_model.md b/src/site/markdown/threat_model.md index 66a48f3..cb293f6 100644 --- a/src/site/markdown/threat_model.md +++ b/src/site/markdown/threat_model.md @@ -74,8 +74,9 @@ because your reader's settings are indistinguishable from configuration you chos ### What is in scope -- The hardening recipes applied by `XmlFactories` to the JAXP implementations it recognizes (stock JDK, Apache Xerces, - Xalan, Saxon, Woodstox, and Android's Expat/KXmlParser). +- The hardening recipes applied by `XmlFactories` to the JAXP implementations it recognizes (stock JDK, Apache Xerces, Xalan, Saxon, and Woodstox). + The recipes for Android's Expat/KXmlParser are applied as best-effort and carry no guarantee + (see **Supported runtimes** under [Assumptions about the environment](#assumptions-about-the-environment)). - A factory returned by `XmlFactories`, used as delivered, that fails to provide a guarantee the Javadoc states it provides. @@ -88,6 +89,21 @@ or read environment variables of its own: each `XmlFactories` method only configures and returns a JAXP factory. Which hardening recipe applies depends on the JAXP implementation present on the classpath. +**Supported runtimes** + +The guarantees are defined on a single runtime family: +OpenJDK 8 or later (and JDK distributions built from it). +On these runtimes the recognized parsers apply the processing limits the guarantees rely on. + +Android, on every API level, carries no guarantee: +no version of Android supports `FEATURE_SECURE_PROCESSING` +(so states [Android's own documentation](https://developer.android.com/reference/javax/xml/parsers/DocumentBuilderFactory#setFeature%28java.lang.String,%20boolean%29)), +the setting the guaranteed processing limits build on. +The library still hardens Android's parsers as best-effort, +tested as complete starting with API level 33 +(see [Supported runtimes](index.html) on the main page), +but a report demonstrated only on Android is [out of scope](#what-is-out-of-scope) on any API level. + **System properties that modify behavior** The library reads a single system property of its own, @@ -99,9 +115,10 @@ Either way the resource is not fetched, so the property selects an error-reporting style, not a security posture. -The library enables secure processing (`FEATURE_SECURE_PROCESSING`) on every -recognized parser and leaves the resulting processing limits (entity expansion, element depth, attribute count, and -similar) at the implementation's own secure default. Those defaults differ by implementation, and on the stock JDK by +The library enables secure processing (`FEATURE_SECURE_PROCESSING`) on every recognized parser that supports it +(no Android parser does, see **Supported runtimes** above) +and leaves the resulting processing limits (entity expansion, element depth, attribute count, and similar) +at the implementation's own secure default. Those defaults differ by implementation, and on the stock JDK by JDK version and the standard `jdk.xml.*` limit properties the JDK itself reads: - On the stock JDK, secure processing honors the `jdk.xml.*` limit properties (for example `jdk.xml.entityExpansionLimit`, @@ -111,7 +128,8 @@ JDK version and the standard `jdk.xml.*` limit properties the JDK itself reads: - The bundled parsers apply their own hardcoded secure defaults instead (for example external Xerces and Woodstox cap entity expansion at `100000`) and do not read `jdk.xml.*`. -Every one of these defaults still bounds entity expansion tightly enough to reject entity-expansion denial of service +On the supported runtimes (see **Supported runtimes** above), +every one of these defaults still bounds entity expansion tightly enough to reject entity-expansion denial of service such as Billion Laughs. **Reserved settings (must not be loosened)** @@ -214,6 +232,10 @@ and reports against a factory reconfigured in any of the ways below are out of s before wrapping it in a `SAXSource`. - The behavior of a JAXP implementation that `XmlFactories` does not recognize (it throws rather than returning an unhardened factory), and any defect in the underlying JAXP implementation itself. +- **Android, on any API level.** + No version of Android supports `FEATURE_SECURE_PROCESSING`, + so the hardening there is best-effort and no guarantee is defined + (see **Supported runtimes** under [Assumptions about the environment](#assumptions-about-the-environment)). ### Downstream responsibility @@ -233,6 +255,9 @@ are **not** vulnerabilities under this model: - XXE, external-entity, SSRF-through-external-reference, or entity-expansion (Billion Laughs) reports against a factory used as delivered. Blocking these is exactly what the hardening does. A working proof against an unmodified instance is a `VALID` finding (see below); a scanner that pattern-matches on parser type is not. +- A report demonstrated only on Android, + where the hardening is best-effort and no guarantee is defined + (see **Supported runtimes** under [Assumptions about the environment](#assumptions-about-the-environment)). - Reports against an instance after the caller installed a resolver (including the `DefaultHandler` passed to `SAXParser.parse(..., DefaultHandler)`) or loosened a reserved setting. - Reports demonstrated on a parser the reporter configured themselves: @@ -257,13 +282,17 @@ A report judged against this model receives exactly one of: | `OUT-OF-SCOPE: reconfigured` | A reserved setting was loosened, or a resolver was installed, on the factory or a produced instance before the reported behavior (see [What is out of scope](#what-is-out-of-scope)). | | `OUT-OF-SCOPE: caller input` | The behavior follows from a top-level URI, a parser instance the caller constructed outside the library, or other input the caller passed directly to a parse call. | | `OUT-OF-SCOPE: foreign implementation` | The behavior is in a JAXP implementation `XmlFactories` does not recognize, or in the underlying JAXP implementation itself. | +| `OUT-OF-SCOPE: unsupported runtime` | The behavior is demonstrated only on a runtime the guarantees are not defined on, such as Android on any API level (see **Supported runtimes** under [Assumptions about the environment](#assumptions-about-the-environment)). | | `MODEL-GAP` | The report fits none of the above. The model is then incomplete: revise it rather than making an ad-hoc call. | ### Conditions that would change this model -Revise this model when any of the following change: a new `XmlFactories` factory method or other public -surface; support for a JAXP implementation beyond those listed under [What is in scope](#what-is-in-scope); -a new reserved setting; or a report that cannot be routed to one of the dispositions above. +Revise this model when any of the following change: +a new `XmlFactories` factory method or other public surface; +support for a JAXP implementation beyond those listed under [What is in scope](#what-is-in-scope); +a change to the supported runtimes (see **Supported runtimes** under [Assumptions about the environment](#assumptions-about-the-environment)); +a new reserved setting; +or a report that cannot be routed to one of the dispositions above. ## Security Vulnerabilities