org.apache.commons.xml.secure (Apache Commons Secure XML 1.0.0 API)
Description: declaration: package: org.apache.commons.xml.secure

# Package org.apache.commons.xml.secure

package org.apache.commons.xml.secure
Apache Commons Secure XML provides secure-by-default JAXP factory creation for Java. A single method call returns a secure JAXP factory that can be used to safely parse XML files.

Every method returns new, secure factory instances. No caching or pooling is performed; callers on a hot path are responsible for their own caching.

A returned factory is not necessarily an instance of the underlying implementation. It might be (and usually is) a wrapper around it, so it cannot be cast to the implementation's own class. Everything else about the implementation's behavior is preserved: features, properties, and attributes delegate to it, and only the security behavior differs.

Preserved behavior includes the choice of internal parsers. Each TrAX, XPath, or schema implementation has its own way of instantiating them, and the library respects it:

- Stock JDK factories use the JDK parsers by default, and expose the `jdk.xml.overrideDefaultParser` feature (and Java system property of the same name) to switch to parsers instantiated through `ServiceLoader`.
- Saxon selects its parsers through its own configuration.

Whichever parser is selected, it is secure.

## Security Guarantees

Every factory returned by this library makes the same three guarantees, regardless of which JAXP implementation is on the classpath:

- External DTDs are not fetched.
- External entities are not resolved.
- Internal entity expansion is bounded by the processing limits the parser applies, so DoS payloads such as Billion Laughs are rejected before they exhaust resources. The library enables `XMLConstants.FEATURE_SECURE_PROCESSING` wherever the JAXP API mandates it, and the limits are then the implementation's secure defaults. The StAX API defines no such feature, and no Android parser supports it, so there the bound is whatever the implementation applies on its own, and this guarantee is best-effort.

These guarantees are defined on OpenJDK 8 or later (and JDK distributions built from it). No version of Android supports `XMLConstants.FEATURE_SECURE_PROCESSING`, so on Android (API level 26 or later) the securing 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 (`setValidating(true)`) or attaches a compiled XSD via `setSchema`: every external resource the validation would otherwise fetch (the DTD itself, an `xsi:schemaLocation` hint, an external entity referenced from the DTD) remains blocked.

Each method adds factory-specific guarantees on top of the three above, documented on the corresponding `newXxxFactory()` method.

Each factory class mirrors every static factory method of its JAXP counterpart:

- the class-name/class-loader overloads and the StAX `newFactory` family (JDK 8),
- `newDefaultInstance()` (Java 9), and
- the namespace-aware `newNSInstance()` family (Java 13).

All of them work, with the same semantics, on every supported runtime, including Java 8. The `newDefaultInstance` methods are an opt-out of JAXP pluggability: they pin the platform's built-in implementation instead of whatever a classpath lookup would resolve, which suits a library with minimal XML requirements that does not want to delegate the choice of implementation to the application developer. The DOM, SAX and schema variants fall back to the standard lookup where the runtime provides neither the Java 9 method nor the JDK's built-in class (for example, Android, whose own lookup is pinned to the platform parser, and whose schema lookup falls back to exactly the Xerces implementation).

An unresolved external reference resolves to empty content by default, so the parse continues without the resource. To reject it with an exception instead, set the system property `org.apache.commons.xml.secure.throwOnUnresolved` to `true`; the property is read at resolution time, and references resolved by a caller-supplied resolver are unaffected.

## Caller-supplied URIs

A top-level URI passed directly by the caller is fetched as-is: `StreamSource(systemId)`, `DocumentBuilder.parse(String)`, or a `SAXSource` built from a system id all cause the JAXP implementation to open that URI without consulting the secure layer. Use a `URIResolver` or `EntityResolver` if you need to restrict the top-level fetch.

## Thread safety

The returned factories inherit the thread-safety properties of the underlying JAXP implementation, which in practice means they are not guaranteed to be thread-safe. Create a new factory per thread or synchronize externally.

- Classes
  Class
  Description
  SecureDocumentBuilderFactory
  Creates new, secure `DocumentBuilderFactory` instances.
  SecureSAXParserFactory
  Creates new, secure `SAXParserFactory` instances.
  SecureSchemaFactory
  Creates new, secure `SchemaFactory` instances.
  SecureTransformerFactory
  Creates new, secure `TransformerFactory` instances.
  SecureXMLInputFactory
  Creates new, secure `XMLInputFactory` instances.
  SecureXPathFactory
  Creates new, secure `XPathFactory` instances.