blob: 39177fcb0e700b7b643d6f26b744aff8a56b33df [file] [view]
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
# Apache XMLSchema Security Threat Model
## §1 Header
- **Project**: Apache XMLSchema — *"a lightweight schema object model
that can be used to manipulate and generate XML schema
representations"* *(documented: `README.txt`)*.
- **Repository**: `apache/ws-xmlschema`.
- **Version / commit**: this model is based on the default branch
at clone time. A report against project release *N* should be triaged
against the model as it stood at *N*, not at HEAD. Latest release
documented in `RELEASE-NOTE.txt`: 2.3.0.
- **Date**: 2026-08-26.
- **Authors**: ASF Security team, awaiting XMLSchema / Webservices
PMC review.
- **Status**: under maintainer review.
- **Reporting**: vulnerabilities that fall under §8 (claimed
properties) should be reported per `SECURITY.md` and the Apache
Security Team disclosure channel (<https://www.apache.org/security/>);
reports that fall under §3 (out of scope) or §9 (properties not
provided) will be closed by XMLSchema triagers citing this document.
- **Provenance legend** —
*(documented)* = drawn from in-repo docs / source comments / project
website with citation;
*(maintainer)* = stated by an XMLSchema maintainer in response to this
threat model;
*(inferred)* = synthesized by the producer from code structure or
domain knowledge, awaiting PMC ratification (every *(inferred)* tag has
a matching §14 question).
- **Model confidence**: 22 documented / 0 maintainer / 24 inferred.
XMLSchema is a Java library that parses, models, walks, and serializes
W3C XML Schema documents (`.xsd` files). It is *not* a document
validator at its core (despite the `xmlschema-walker` providing some
validation helpers): the primary product is the in-memory object model
of a schema, and the schema-imports / schema-includes resolver that lets
a `<xs:include>` or `<xs:import>` pull in additional schemas from a
URI. XMLSchema is consumed primarily by SOAP stacks (Apache CXF, Apache
Axis) and other code-generation / data-binding tooling. It is bundled
into runtimes that ingest WSDLs and policy documents.
## §2 Scope and intended use
### Intended use
- In-process parsing and manipulation of W3C XML Schema documents in
Java, primarily as part of a tooling pipeline (WSDL import,
code generation, data-binding) or as part of a SOAP stack at runtime
*(documented: `README.txt`)*.
- Three modules ship: `xmlschema-core` (the object model + parser +
serializer + URI resolver), `xmlschema-walker` (visitor-style schema
walking + a `XmlSchemaElementValidator` used for tooling), and
`xmlschema-bundle-test` (an OSGi bundle integration test). The
`w3c-testcases` directory holds the W3C test suite for regression
testing only.
### Deployment shape
XMLSchema is an in-process Java library. There is no daemon, no
network listener, no CLI. The threat model is therefore that of an
**XML-parsing library that performs caller-directed network or
filesystem IO** when it follows `<xs:include>` / `<xs:import>` /
`schemaLocation` references *(inferred — §14 Q2)*.
### Caller roles
| Role | Trust level | Notes |
| --- | --- | --- |
| **Embedding Java application** | trusted | Calls `XmlSchemaCollection.read(...)`, decides whether the input stream came from disk, classpath, or wire; decides which `URIResolver` to plug in. |
| **`URIResolver` implementation** | trusted | Either the bundled `DefaultURIResolver` (which constructs a `URL` from the parent schema's base URI + the `schemaLocation` and returns an `InputSource` pointing at it) or a caller-supplied resolver *(documented: `xmlschema-core/src/main/java/.../resolver/DefaultURIResolver.java`)*. A hostile resolver is out of model. |
| **`ExtensionRegistry` implementation** | trusted | Pluggable via system property `org.apache.ws.commons.schema.extension_registry` *(documented: `xmlschema-core/src/main/java/org/apache/ws/commons/schema/XmlSchemaCollection.java` line 361)*. |
| **Producer of the schema bytes** (`Reader`, `InputStream`, `InputSource`, `Source`, `Document`, `Element`) | **variable** — see §6 trust table | The *only* attacker-controllable input position; in many embeddings the schema bytes come from a WSDL fetched off the wire. |
| **Producer of imported / included schemas** (resolved by the `URIResolver`) | **variable** — typically as untrusted as the parent schema, but can be a *different* origin if the parent's `<xs:import schemaLocation="http://attacker/evil.xsd">` points elsewhere | Following an `xs:import` is a **second, possibly cross-origin, fetch**. This is the principal SSRF surface. |
| **JDK XML platform** (`DocumentBuilderFactory`, `TransformerFactory`, `SchemaFactory`) | trusted upstream | XMLSchema sets `FEATURE_SECURE_PROCESSING=true` on the factories it constructs. Its internal schema parser also rejects DOCTYPE declarations by default and disables external DTD and external entity resolution; `org.apache.ws.commons.schema.allowDTD=true` accepts DOCTYPE-bearing schema documents while keeping external resolution disabled. |
### Component-family table
| Family | Representative entry point | Touches outside the process? | In-model? |
| --- | --- | --- | --- |
| `xmlschema-core` object model — `XmlSchema*` types, `XmlSchemaCollection`, `SchemaBuilder` | `XmlSchemaCollection.read(InputSource, ...)` and overloads | **no** for in-memory model; **yes** when the URI resolver follows `xs:import`/`xs:include` | **yes** |
| `xmlschema-core` URI resolver — `DefaultURIResolver`, `CollectionURIResolver`, `URIResolver` | `XmlSchemaCollection.setSchemaResolver()` | **yes** — by design, fetches imported schemas | **yes** |
| `xmlschema-core` serializer — `XmlSchemaSerializer` | `XmlSchema.write(OutputStream)` | **no** | **yes** |
| `xmlschema-core` resource loader (internal) — hardened `DocumentBuilderFactory` and `TransformerFactory` instances | invoked by `XmlSchemaCollection.read(InputSource, ...)`, recursive schema reparses, and `XmlSchema.write(...)` | **no** except where the URI resolver fetches imported schemas before parsing | **yes** |
| `xmlschema-walker` visitor — `XmlSchemaWalker`, `XmlSchemaVisitor`, `XmlSchemaScope` | walked by a caller-supplied `XmlSchemaVisitor` | **no** | **yes** |
| `xmlschema-walker` element validator — `XmlSchemaElementValidator` | walked at SAX-event time; consults the schema model | **no** (operates on caller-supplied SAX events) | **yes** |
| `xmlschema-walker` document path finder — `XmlSchemaPathFinder` | walked at SAX-event time; matches events against the schema model | **no** (operates on caller-supplied SAX events) | **yes** |
| `xmlschema-walker` DOM-from-SAX helper — `DomBuilderFromSax` | builds a DOM out of SAX events for validator inspection | **no** | **yes** |
| `xmlschema-bundle-test` | OSGi packaging regression test | n/a | **out of model** *(§3)* |
| `w3c-testcases/` | W3C schema test data | n/a | **out of model** *(§3)* |
A finding is in-model only if it reaches a row marked **yes**.
## §3 Out of scope (explicit non-goals)
1. **XML *document* validation against a schema.** XMLSchema is a
*schema* model; the only validation-like artifact is
`xmlschema-walker`'s `XmlSchemaElementValidator` used in tooling
contexts. Findings that depend on the JDK `Validator` /
`SchemaFactory` behavior or on third-party validators built on
XMLSchema's model are out of model *(inferred — §14 Q3)*. →
`OUT-OF-MODEL: out-of-layer`.
2. **A SOAP / WSDL parser.** XMLSchema parses the *embedded* `<schema>`
element of a WSDL, but the WSDL parser itself is upstream (e.g.
Apache WSDL4J, Apache CXF). → `OUT-OF-MODEL: out-of-layer`.
3. **`SchemaFactory` of the JDK.** XMLSchema does not wrap or replace
the JDK's `javax.xml.validation.SchemaFactory`. The two are different
abstractions *(inferred — §14 Q3)*. → `OUT-OF-MODEL: out-of-layer`.
4. **`xmlschema-bundle-test` and `w3c-testcases/`.** Integration test
harness and W3C regression data. → `OUT-OF-MODEL: unsupported-component`.
5. **The XML parser bytes-to-DOM step when the caller provides a
pre-parsed `Document` / `Element`.** `XmlSchemaCollection.read(Document)`
and `.read(Element)` accept a caller-parsed DOM; if the caller's
`DocumentBuilderFactory` is not hardened, XMLSchema does not
retroactively secure it *(inferred — §14 Q4)*. →
`OUT-OF-MODEL: trusted-input`.
6. **The remote host reached when following an `xs:include` /
`xs:import`.** The URI is in the input schema; XMLSchema follows it.
What the remote host returns is data XMLSchema then parses, but the
*integrity* of the remote host is not WSS4J's concern *(inferred —
§14 Q5)*. → `OUT-OF-MODEL: adversary-not-in-scope` for malicious
*remote* peer; `VALID` if XMLSchema is tricked into the fetch in the
first place by a path the §7 model permits.
7. **Replacement `URIResolver` / `ExtensionRegistry` implementations.**
Caller-pluggable; a hostile resolver is out of model.
8. **Code shipped in `w3c-testcases/`, `*/src/test/`, `etc/`,
`xmlschema-bundle-test/`.** Test data and supporting fixtures.
→ `OUT-OF-MODEL: unsupported-component`.
## §4 Trust boundaries and data flow
| # | Transition | Authentication | Authorization |
| --- | --- | --- | --- |
| B1 | Caller → `XmlSchemaCollection.read(InputSource | Reader | Source | Document | Element)` | none — caller is trusted | none |
| B2 | `XmlSchemaCollection.read(InputSource, ...)` → hardened JDK `DocumentBuilder` | none | DOCTYPE rejected by default; external DTD/entity resolution disabled |
| B3 | Schema parser → `URIResolver.resolveEntity(namespace, schemaLocation, baseUri)` | none | bundled `DefaultURIResolver` does **no host filtering**: it constructs `new URL(new URL(baseUri), schemaLocation)` and hands back an `InputSource` pointing at it |
| B4 | Resolved `InputSource` → `XmlSchemaCollection.read(InputSource, ...)` (recursive) | none | none |
| B5 | `XmlSchema.write(...)` → JDK `TransformerFactory` (with `FEATURE_SECURE_PROCESSING=true` and external DTD/stylesheet access disabled where supported) | none | none |
| B6 | `XmlSchemaCollection` ctor → `System.getProperty("org.apache.ws.commons.schema.extension_registry")` → `Class.forName()` | none | trusts system properties to be operator-controlled |
### Reachability preconditions per family
- **`xmlschema-core` parser** (`XmlSchemaCollection.read(InputSource)`,
`.read(Reader)`, `.read(Source)` for non-`DOMSource` sources): in-model
when the bytes are
attacker-controllable. XMLSchema sets `FEATURE_SECURE_PROCESSING=true`
on its internal `DocumentBuilderFactory`, rejects DOCTYPE declarations
by default, disables external general entities, external parameter
entities, and external DTD loading, and installs a no-op SAX
`EntityResolver`. Setting
`org.apache.ws.commons.schema.allowDTD=true` accepts DOCTYPE-bearing
schema documents but keeps external DTD and external entity resolution
disabled.
- **`xmlschema-core` URI resolver** (`DefaultURIResolver`): in-model
for SSRF / cross-origin fetch when the input schema is attacker-
controlled and contains an `xs:import schemaLocation="…"`. The
bundled resolver constructs `new URL(...)` and returns an `InputSource`;
the JDK then fetches it on `parse()`.
- **`xmlschema-core` parser fed a pre-parsed DOM** (`read(Document)`,
`read(Element)`): out of model for XXE; the caller's
`DocumentBuilderFactory` decided that. In-model for whatever the
schema-model semantics imply about the DOM contents.
- **`xmlschema-walker`**: in-model when the visitor walks an
attacker-controlled schema. The walker is purely in-memory. Before cycle
detection, malformed but parseable schemas could create cycles in type
derivation, substitution groups, model groups, or attribute groups and
recurse until `StackOverflowError`. The walker now tracks these expansion
paths and rejects cyclic re-entry with `XmlSchemaException`; recursion that
crosses an element declaration remains supported.
- **`XmlSchemaPathFinder`**: in-model when caller-supplied SAX events
are matched against an attacker-controlled schema. Its backtracking
work is bounded per document by configurable decision-point and
replay-event limits.
- **`XmlSchemaElementValidator` / `DomBuilderFromSax`**: in-model only
insofar as they parse SAX events the caller hands in. `DomBuilderFromSax`
sets `FEATURE_SECURE_PROCESSING=true` on its
`DocumentBuilderFactory` *(documented:
`xmlschema-walker/src/main/java/.../docpath/DomBuilderFromSax.java`
line 81)*.
## §5 Assumptions about the environment
- **JDK**: minimum Java 17 in the 2.3.0 release; earlier releases
supported Java 7 *(documented: `RELEASE-NOTE.txt`)*.
- **JDK XML platform**: assumes a conformant `DocumentBuilderFactory`,
`TransformerFactory`, and SAX parser. XMLSchema applies explicit DTD and
external access controls to its internal schema parser and transformer,
while unsupported optional JAXP features are ignored so the remaining
controls still apply.
- **Network**: the bundled `DefaultURIResolver` will issue HTTP / HTTPS
/ `file://` / `jar:` fetches via the JDK URL handlers when an `xs:include` /
`xs:import schemaLocation` is followed. Whether the JVM has a proxy
configured, a `SecurityManager`, or any URL-scheme restriction is
out of XMLSchema's control *(documented: `DefaultURIResolver.java`)*.
- **Filesystem**: caller-supplied paths; XMLSchema does no path
sanitization of `schemaLocation` values that begin with `file://`
*(inferred — §14 Q7)*.
- **Memory**: schemas are held in memory; XMLSchema has no built-in
ceiling on schema-document size, imported bytes, or fetch rate. Import
and include resolution is bounded per read by a default maximum depth of
64 and maximum of 1000 resolved schema documents, and schema-model
construction is bounded by a default structural nesting depth of 512;
these limits are configurable with JVM system properties. The walker has
active-path cycle detection for the schema expansion graphs it traverses,
but large acyclic schemas may still consume substantial memory and CPU
*(documented: `README.txt`)*.
- **System properties**: `org.apache.ws.commons.schema.extension_registry`
is consulted at `XmlSchemaCollection` construction time, and the
named class is loaded via `Class.forName()` *(documented:
`XmlSchemaCollection.java` line 361)*. This is a startup-time
privilege escalation surface if the system property can be set by
an untrusted actor *(inferred — §14 Q9)*.
- **Wrap in `AccessController.doPrivileged`**: XMLSchema brackets the
schema parse and the system-property read in
`AccessController.doPrivileged` to be JDK-SecurityManager-compatible
on pre-17 JDKs *(documented: `XmlSchemaCollection.java` lines 376,
745)*. On JDK 17+ the SecurityManager is deprecated.
### What XMLSchema does *not* do to its host (negative claims, awaiting maintainer ratification)
- Opens **no** listening sockets *(inferred — §14 Q10)*.
- Spawns **no** child processes *(inferred — §14 Q10)*.
- Installs **no** signal handlers *(inferred — §14 Q10)*.
- Reads only the documented system property
`org.apache.ws.commons.schema.extension_registry` for
security-relevant decisions; does **not** consume `LD_*`-style
envvars *(inferred — §14 Q10)*.
- Writes **nothing** to the filesystem of its own initiative; the
`XmlSchemaSerializer` writes to the `OutputStream` the caller hands
in *(inferred — §14 Q10)*.
## §5a Build-time and configuration variants
XMLSchema is a single Maven artifact set (`xmlschema-core`,
`xmlschema-walker`, `xmlschema-bundle-test`). There are **no
compile-time feature toggles** *(inferred — §14 Q11)*. The runtime
security envelope is shaped by a small set of *runtime extension
points*:
| Knob | Default | Maintainer stance | Effect |
| --- | --- | --- | --- |
| `org.apache.ws.commons.schema.extension_registry` system property | unset *(documented: `XmlSchemaCollection.java` line 361)* | dev-time customization; if set by an untrusted actor the named class is loaded into the JVM | extension-registry class is `Class.forName`-loaded at `XmlSchemaCollection` ctor time |
| `XmlSchemaCollection.setSchemaResolver(URIResolver)` | `DefaultURIResolver` *(documented: `DefaultURIResolver.java`)* | **maintainer ruling required** — is the documented expectation that production deployments install a *restricted* resolver that refuses untrusted hosts (proposed: **yes, §10**), or is the default resolver supported as production-safe? *(inferred — §14 Q12)* | controls whether `xs:include`/`xs:import` may reach the network |
| `XmlSchemaCollection.setBaseUri(String)` | unset *(documented)* | caller-supplied | base URI against which relative `schemaLocation` values resolve |
| `org.apache.ws.commons.schema.walker.maxDecisionPoints` system property | `10000` *(documented: `XmlSchemaPathFinder.java`)* | operator-tunable per-process limit | maximum decision points created while matching one document |
| `org.apache.ws.commons.schema.walker.maxReplayedEvents` system property | `1000000` *(documented: `XmlSchemaPathFinder.java`)* | operator-tunable per-process limit | maximum previously traversed events replayed while backtracking through one document |
| `org.apache.ws.commons.schema.maxImportDepth` system property | `64` *(documented: `README.txt`)* | operator-tunable per-process limit | maximum import/include resolution depth for one schema read |
| `org.apache.ws.commons.schema.maxSchemaResolutions` system property | `1000` *(documented: `README.txt`)* | operator-tunable per-process limit | maximum schema documents resolved during one top-level read |
| `org.apache.ws.commons.schema.maxNestingDepth` system property | `512` *(documented: `README.txt`)* | operator-tunable per-process limit | maximum structural nesting depth while building the schema model, including nested include/import/redefine document resolutions |
| `org.apache.ws.commons.schema.allowDTD` system property | `false` *(documented: `README.txt`)* | compatibility toggle for operator-controlled deployments | allows DOCTYPE declarations in schema documents; external DTD and external entity resolution remain disabled |
| `DocumentBuilderFactory` provider | JDK default (typically Xerces fork) *(inferred — §14 Q6)* | depends on the JDK | shape of XML parsing for `read(InputSource)` / stream-shaped `read(Source)` paths |
### The insecure-default case
The bundled `DefaultURIResolver` **does follow remote URLs by default**.
The maintainer ruling captured in §14 Q12 will determine whether
"a schema with `<xs:import schemaLocation='http://attacker/'/>` fetched
the URL during parse" is a `VALID` report (production deployments
should be protected by the default) or an `OUT-OF-MODEL:
non-default-build` report (production deployments are *documented* as
required to install a restricting resolver per §10).
XMLSchema's internal schema parser rejects DOCTYPE declarations by
default and disables external DTD and external entity resolution. This
applies both to top-level `read(InputSource | Reader | Source)` non-DOMSource
paths
parses and to recursive import/include/redefine reparses. Operators may
set `org.apache.ws.commons.schema.allowDTD=true` to accept
DOCTYPE-bearing schemas for compatibility; external DTD and external
entity resolution remain disabled in that mode.
## §6 Assumptions about inputs
### Per-entry-point trust table
| Entry point | Parameter | Attacker-controllable? | Caller must enforce |
| --- | --- | --- | --- |
| `XmlSchemaCollection.read(InputSource is)` | `is` bytes | **yes** | XMLSchema rejects DOCTYPE by default and disables external DTD/entity resolution; caller may need to install a restricting `URIResolver` if the source contains untrusted `xs:include`/`xs:import` |
| `XmlSchemaCollection.read(Reader r)` | `r` characters | **yes** | same as above |
| `XmlSchemaCollection.read(Source src)` | `src` | **yes** | `SAXSource`/`StreamSource`/other route through the internal hardened factory (same as `read(InputSource)`); a `DOMSource` routes to the pre-parsed `read(Document)`/`read(Element)` path, so the upstream parser's XXE/DTD posture applies |
| `XmlSchemaCollection.read(Document doc)` | `doc` | **yes if doc was parsed from untrusted bytes** | caller's `DocumentBuilderFactory` is responsible for XXE / DTD posture; XMLSchema does not re-parse |
| `XmlSchemaCollection.read(Element el)` | `el` | same as `read(Document)` | same as above |
| `XmlSchemaCollection.setSchemaResolver(URIResolver)` | resolver | caller-supplied | replacing the default is the documented path for production hardening *(inferred — §14 Q12)* |
| `XmlSchemaCollection.setBaseUri(String)` | `baseUri` | **caller-supplied trusted string** | not validated; if attacker can set this they can pivot the import-resolver origin |
| `XmlSchemaCollection.setExtReg(ExtensionRegistry)` | registry | caller-supplied | caller's choice |
| `XmlSchema.write(OutputStream)` / `XmlSchema.write(Writer)` | output sink | caller-supplied | caller's choice; `FEATURE_SECURE_PROCESSING=true` is set on the internal `TransformerFactory`, with external DTD/stylesheet access disabled where supported |
| `XmlSchemaWalker.walk(XmlSchemaElement)` | walked schema | as untrusted as the schema | none — pure in-memory walking |
| `XmlSchemaPathFinder` | SAX events + schema model | as untrusted as both | configure backtracking limits for the deployment; defaults bound decision points and replayed events per document |
| `XmlSchemaElementValidator` (walker module) | SAX events + schema model | as untrusted as both | caller validates / sanitizes outside |
| `DomBuilderFromSax` | SAX events | as untrusted as the source of the events | `FEATURE_SECURE_PROCESSING=true` is set *(documented: `DomBuilderFromSax.java` line 81)* |
| System property `org.apache.ws.commons.schema.extension_registry` | class name | **trusted by §3 item 7** | operator must lock down property setting in shared-JVM deployments |
### Size / shape / rate
- No documented limit on schema-document size *(inferred — §14 Q8)*.
- Import/include resolution has a default maximum depth of 64 and a
default maximum of 1000 resolved schema documents per top-level read;
both limits are configurable with JVM system properties *(documented:
`README.txt`)*.
- Schema-model construction has a default maximum structural nesting depth
of 512, including nested include/import/redefine document resolutions;
the limit is configurable with a JVM system property *(documented:
`README.txt`)*.
- Walker expansion cycles are rejected for type derivation, substitution
groups, model groups, and attribute groups. This prevents recursive
stack exhaustion for malformed but parseable schemas; it is not a general
limit on the size or cost of an acyclic schema.
- No rate limit on URL fetches when following `xs:import`
*(inferred — §14 Q12)*.
- `XmlSchemaPathFinder` bounds decision points and replayed events per
document by default; these limits are configurable through the
`org.apache.ws.commons.schema.walker.maxDecisionPoints` and
`org.apache.ws.commons.schema.walker.maxReplayedEvents` system
properties *(documented: `XmlSchemaPathFinder.java`)*.
## §7 Adversary model
### Actors
| Actor | In scope? | Capabilities |
| --- | --- | --- |
| **Producer of the input schema bytes** | **yes** | full byte control of the schema; can include `<xs:import schemaLocation="…"/>` pointing anywhere |
| **Producer of an imported schema** at a URL the parent schema references | **yes** | returns a malicious downstream `.xsd` after the parent triggers the fetch |
| **Network attacker on the path between XMLSchema and an HTTP `schemaLocation`** | **partial** *(inferred — §14 Q13)* — TLS is the JDK URL handler's concern; XMLSchema does no certificate pinning; if the operator allowed plain `http://` fetches a network attacker can substitute |
| **In-process callers (the embedding application)** | **out of scope** | trivially full control |
| **Owner of the host filesystem** | **out of scope** | by construction |
| **Author of a hostile `URIResolver` / `ExtensionRegistry`** | **out of scope** *(§3 item 7)* |
| **Author of system-property setting on JVM startup** | **out of scope** if operator-controlled; in scope only when an untrusted actor can set `org.apache.ws.commons.schema.extension_registry` *(inferred — §14 Q9)* |
| **Co-tenant on the same JVM** (multi-app servlet container) | **out of scope** *(inferred — §14 Q14)* |
| **Side-channel observer** | **out of scope** *(inferred — §14 Q14)* |
| **Quantum adversary** | **out of scope** |
## §8 Security properties the project provides
### P1 — Memory-safety on the schema parse, given a JDK conformant to §5
- **Condition**: bytes arrive through one of the `read(...)` paths; the
JDK platform supplies a working `DocumentBuilder`; XMLSchema sets
`FEATURE_SECURE_PROCESSING=true` on its factories.
- **Violation symptom**: a crafted `.xsd` causes XMLSchema's *own*
code (not the JDK XML parser) to throw an unhandled exception that
is **not** a `XmlSchemaException` / `ParserConfigurationException` /
`IOException` / `SAXException` — i.e. crashes outside the documented
failure mode. Memory corruption is JVM-level and not a Java-side
defect.
- **Severity**: typically **correctness-only** (Java does not have
memory corruption); `VALID-HARDENING` if the symptom is an
unhandled `RuntimeException` that the caller cannot catch through
the documented surface *(inferred — §14 Q15)*.
- *(inferred — §14 Q15)*
### P2 — Internal parser DTD and external-entity hardening
- **Condition**: XMLSchema's `read(InputSource | Reader | Source)`
non-DOMSource paths take the internal `DocumentBuilderFactory`.
- **Property**: DOCTYPE declarations are rejected by default. External
general entities, external parameter entities, external DTD loading,
and JAXP external-DTD access are disabled; a no-op `EntityResolver` is
installed as a fallback. If
`org.apache.ws.commons.schema.allowDTD=true` is set, DOCTYPE
declarations may be accepted but external DTD/entity resolution remains
disabled.
- **Violation symptom**: attacker-controlled schema bytes cause the
internal parser to fetch or expand external DTD/entity content, or a
DOCTYPE is accepted while `allowDTD` is unset.
- **Severity**: **high** for external file disclosure / SSRF through XXE;
**medium** for parser-resource exhaustion when the embedding application
accepts untrusted schemas.
### P3 — Round-trip parse → model → serialize consistency
- **Condition**: a well-formed schema is parsed and serialized; the
serializer's `TransformerFactory` is configured with
`FEATURE_SECURE_PROCESSING=true`.
- **Violation symptom**: a serialized schema is not a valid XSD, or
differs semantically from the parsed one *(inferred — §14 Q16)*.
- **Severity**: **correctness-only**; not security-relevant unless the
divergence creates a security-meaningful misinterpretation downstream
*(inferred — §14 Q16)*.
- *(inferred — §14 Q16)*
### P4 — `xmlschema-walker` deterministic visit order
- **Condition**: visitor pattern is invoked on the in-memory model.
- **Violation symptom**: visit order varies across invocations on the
same model, breaking caller assumptions.
- **Severity**: **correctness-only**.
- *(inferred — §14 Q17)*
### P5 — Bounded recursive schema walking
- **Condition**: an attacker-controlled schema is passed to
`XmlSchemaWalker.walk(XmlSchemaElement)`.
- **Property**: cyclic type derivation, substitution-group, model-group,
and attribute-group expansions terminate with `XmlSchemaException` rather
than recursing indefinitely. Legal recursive content that passes through
an element declaration remains walkable.
- **Violation symptom**: a parseable schema causes the walker to recurse
until `StackOverflowError` or another resource-exhaustion failure.
- **Severity**: **medium** availability impact when the embedding
application accepts untrusted schemas *(inferred — §14 Q23)*.
### P6 — Bounded schema-model structural descent
- **Condition**: attacker-controlled schema bytes or DOM content are passed
to `XmlSchemaCollection.read(...)`.
- **Property**: deeply nested schema structure, including depth split across
nested include/import/redefine document resolutions, terminates with
`XmlSchemaException` instead of exhausting the Java thread stack.
- **Violation symptom**: a parseable schema causes `SchemaBuilder` to recurse
until `StackOverflowError` or another resource-exhaustion failure.
- **Severity**: **medium** availability impact when the embedding
application accepts untrusted schemas.
## §9 Security properties the project does *not* provide
State each plainly so a triager can route an inbound report to the
matching disclaimer.
- **No SSRF defense on `xs:import`/`xs:include schemaLocation` URLs.**
The bundled `DefaultURIResolver` constructs a `URL` from the parent
schema's base URI plus the schema-location value and returns an
`InputSource` pointing at it. The JDK then fetches it on parse.
XMLSchema applies *no* allowlist, *no* protocol restriction, and *no*
host filtering of any kind. The caller is responsible for installing
a restricting `URIResolver` if the input schema is attacker-controlled
*(documented: `DefaultURIResolver.java`)*.
- **No guarantee that DTD-bearing schemas are accepted by default.**
XMLSchema rejects DOCTYPE declarations on its internal parser unless
`org.apache.ws.commons.schema.allowDTD=true` is set. The compatibility
mode still disables external DTD and external entity resolution.
- **No defense when the caller passes in a pre-parsed `Document` or
`Element`.** The hardening on the internal `DocumentBuilderFactory`
is moot — the caller's parser produced the DOM *(documented:
`XmlSchemaCollection.read(Document)` / `.read(Element)`)*.
- **No bound on schema-document size, imported bytes, or fetch rate.**
Import/include depth, total resolved documents per top-level read, and
structural nesting depth are bounded, but a schema can still consume
substantial resources within those limits *(inferred — §14 Q8; resource
limits documented in `README.txt`)*.
- **No protection of imported schemas at rest.** Schemas pulled from
HTTP are fetched in cleartext if the URL is `http://`. The caller
must use TLS-protected URLs or install a restricting resolver
*(documented: `DefaultURIResolver.java`)*.
- **No defense against the system-property-controlled
`ExtensionRegistry` being a malicious class.** The named class is
loaded into the running JVM and instantiated.
- **No data-at-rest protection.** Schemas serialized by
`XmlSchemaSerializer` are plain XML on whatever sink the caller
provided.
- **No constant-time guarantees.** XMLSchema does not deal with
secrets.
- **No defense against side-channel observation.**
- **No quantum resistance.**
### False-friend properties (call out separately)
- **`org.apache.ws.commons.schema.allowDTD=true` looks like it restores
legacy XML parser behavior, but it does not restore external DTD or
external entity fetching.** The toggle accepts DOCTYPE declarations for
compatibility only; external fetches remain disabled.
- **`DefaultURIResolver` looks like a sandbox, but it isn't.** It is
the *bundled* resolver; its job is to resolve `xs:include`/`xs:import`,
not to filter destinations.
- **`XmlSchemaCollection.setBaseUri(String)` looks like a chroot for
imports, but it isn't.** If the importing schema sets an absolute
URL in `schemaLocation`, the base URI is irrelevant — the absolute
URL wins *(inferred — §14 Q18)*.
- **`xmlschema-walker.XmlSchemaElementValidator` looks like a
document validator, but it is a tooling helper.** It is not a
drop-in replacement for `javax.xml.validation.Validator` and does
not promise XSD-1.0 / 1.1 conformance *(inferred — §14 Q3)*.
### Well-known attack classes XMLSchema does not single-handedly defend against
- **XXE / external-entity disclosure** when the caller pre-parses a DOM
with an unsafe XML parser before calling `read(Document)` /
`read(Element)`. XMLSchema's internal parser path rejects DOCTYPE by
default and disables external DTD/entity resolution.
- **SSRF via `xs:import schemaLocation`** — see §9 first bullet.
- **Billion-laughs / quadratic blowup** — partially mitigated by
`FEATURE_SECURE_PROCESSING=true`, but not universally.
- **Schema-amplification DoS** — large or heavily-recursive acyclic schemas
can exhaust memory or CPU within the documented resource limits;
structural nesting and cyclic walker expansion are rejected as described
in §8 P5 and §8 P6.
- **Confused-deputy fetch via untrusted `baseUri` + relative
`schemaLocation`** — the operator-supplied base URI is trusted.
## §10 Downstream responsibilities
The embedding Java application **must**:
1. Decide whether the schema bytes being parsed are
attacker-controllable. If yes, install a restricting
`URIResolver` via `XmlSchemaCollection.setSchemaResolver(...)` that
refuses arbitrary `http://` / `https://` / `file://` / `jar:` /
`ftp:` URLs. The bundled `DefaultURIResolver` does not filter
*(documented: `DefaultURIResolver.java`)*.
2. When passing a pre-parsed `Document` / `Element` into
`XmlSchemaCollection.read(...)`, use a `DocumentBuilderFactory`
hardened against XXE — specifically with `disallow-doctype-decl=true`
and external-entity processing disabled.
3. Do not enable `org.apache.ws.commons.schema.allowDTD=true` for
attacker-controlled schema bytes unless compatibility requires it and
the deployment accepts internal DTD subset processing. External DTD and
external entity resolution remain disabled by XMLSchema in that mode.
4. Bound maximum schema size, imported bytes, and fetch rate at the
*caller* level. XMLSchema provides configurable import/include depth
per-read resolution, and structural nesting limits, but these do not
replace deployment-specific resource budgets *(inferred — §14 Q8)*.
5. Set `org.apache.ws.commons.schema.extension_registry` only at JVM
startup from a trusted source; do not allow untrusted actors to set
it.
6. Set `XmlSchemaCollection.setBaseUri(...)` from an operator-trusted
string, not from anywhere an attacker can influence.
7. Run on a release-supported branch (currently 2.3.0 line)
*(documented: `RELEASE-NOTE.txt`)*.
The embedding Java application **should** additionally implement these
defense-in-depth controls:
1. Enforce URL scheme and destination restrictions in the resolver:
allow only `https://` to approved hosts; deny `file://`, `jar:`,
loopback, link-local, and RFC1918/private address ranges.
2. Keep `org.apache.ws.commons.schema.allowDTD` unset unless a deployment
has known DTD-bearing schema inputs and has tested the compatibility
mode on its JDK XML provider.
3. Supplement XMLSchema's import/include depth, per-read resolution, and
structural nesting limits with caller-boundary budgets for total imported
bytes and fetch rate per top-level parse.
4. Use connect/read timeouts for import fetches and fail closed on
timeout or policy-check errors.
5. Log import-resolution decisions (requested URI, normalized target,
allow/deny result, reason) for incident response and triage.
6. Prefer integrity-controlled schema sources (pinned internal mirror
or checksum-verified artifacts) instead of live internet fetches.
## §11 Known misuse patterns
- **Passing an attacker-controlled `.xsd` to
`XmlSchemaCollection.read(InputSource)` with the
`DefaultURIResolver` in place.** The schema's `xs:include` /
`xs:import` are followed unrestricted, leading to SSRF / cross-origin
fetch / `file://` disclosure *(documented:
`DefaultURIResolver.java`)*. The fix is per §10 item 1.
- **Trusting `read(Document)` / `read(Element)` to inherit XXE
defenses from XMLSchema.** XMLSchema does not re-parse; the caller's
factory chose the posture.
- **Setting `org.apache.ws.commons.schema.extension_registry` from a
servlet-context init parameter or a config file an end user can
influence.** The named class is loaded and instantiated at
`XmlSchemaCollection` construction.
- **Treating `XmlSchemaElementValidator` (walker module) as a
conformant XSD validator.** It is a tooling helper; conformant
document validation against an XSD requires the JDK
`javax.xml.validation.Validator` *(inferred — §14 Q3)*.
- **Using the same `XmlSchemaCollection` instance across thread
boundaries without external synchronization.** XMLSchema does not
document its threading model *(inferred — §14 Q19)*.
- **Fetching imported schemas over plain `http://` from a remote
registry.** The operator should restrict to `https://` or pin to a
trusted mirror.
- **Letting the parsed schema's base URI be derived from the
attacker-controlled bytes** (e.g. an absolute `xmlns:tns` URL the
attacker provided) and then walking the URI graph from that base.
## §11a Known non-findings (recurring false positives)
This section is the highest-leverage input for automated agentic
security scans. Each entry: tool symptom, why it is safe under the
model, the section that licenses the call.
- **"`new URL(baseUri, schemaLocation).openConnection()` — SSRF risk in
`DefaultURIResolver`."** Bundled behavior, explicitly documented as
defaulted unrestricted; operator must install a restricting resolver
per §10 item 1. → `OUT-OF-MODEL: trusted-input` *(if the maintainer
rules at Q12 that the default is dev/test)*, or `VALID-HARDENING`
*(if the maintainer rules the default is supported)*.
- **"`DocumentBuilderFactory.newInstance()` allows XXE in
`XmlSchemaCollection`."** Current XMLSchema internal parsing rejects
DOCTYPE by default and disables external DTD/entity resolution. A report
must show a bypass of those controls to be `VALID`.
- **"`Class.forName(System.getProperty(...))` is dynamic-class-loading."**
Documented extension point; the system property is the trust gate
*(documented: `XmlSchemaCollection.java` line 361)*. → `OUT-OF-MODEL:
trusted-input`.
- **"`AccessController.doPrivileged` deprecated in JDK 17."** JDK
compatibility wrapper; deprecation is informational on JDK 17 and
required on pre-17 JDKs. → `KNOWN-NON-FINDING`.
- **"Hardcoded password in test resources."** No such resource exists
in this repo; if a tool flags `w3c-testcases/` data, it is W3C
conformance suite data *(documented: top-level `w3c-testcases/`)*. →
`OUT-OF-MODEL: unsupported-component`.
- **"`XmlSchemaSerializer` uses identity Transformer — could be
exploited via XSLT injection."** Identity transform; no stylesheet
reachable from input *(documented: `XmlSchema.java`)*. →
`KNOWN-NON-FINDING`.
- **"`URLConnection.getInputStream()` without timeout."** True;
XMLSchema does no read-timeout on fetched imports
*(inferred — §14 Q12)*. → `VALID-HARDENING` if Q12 rules the
default-resolver is production-safe; otherwise documented as a §10
responsibility.
- **"Path traversal via `XmlSchemaCollection.setBaseUri()`."** Caller-
supplied trusted string per §6. → `OUT-OF-MODEL: trusted-input`.
- **"Schemas in `w3c-testcases/` contain wide-open DTDs."** W3C
conformance suite, used as input to unit tests *(documented:
top-level `w3c-testcases/`)*. → `OUT-OF-MODEL: unsupported-component`.
- **"`ExtensionRegistry` is `Class.forName`-loaded — RCE."** Trusted
system property per §3 item 7. → `OUT-OF-MODEL: trusted-input`.
- **"`XmlSchemaCollection.read(InputSource)` with a `file://` system ID
follows it to read arbitrary local files."** (No `read(URL)` or
`read(InputStream)` overload exists; earlier revisions of this table
listed both in error.) Caller passed the URL; trusted entry point.
→ `OUT-OF-MODEL: trusted-input`.
## §12 Conditions that would change this model
Revise this document when any of the following lands:
- A change in the default `URIResolver` behavior — e.g. adding host
filtering, refusing non-HTTPS, or adding read/connect timeouts.
- A change in the default parser DTD/XXE posture, including the
`org.apache.ws.commons.schema.allowDTD` compatibility contract.
- A new public entry point on `XmlSchemaCollection` that accepts new
input shapes.
- A new built-in resource limit, or a change to an existing resource
limit.
- A new feature flag in `xmlschema-walker`'s validator that turns it
into a claimed-conformant document validator.
- An upgrade of the supported JDK minimum that changes the JDK XML
provider behavior.
- A change in the system-property contract for `ExtensionRegistry`.
- A vulnerability report that cannot be cleanly routed to one of the
§13 dispositions — evidence the model has a gap.
## §13 Triage dispositions
A report against XMLSchema receives exactly one of the following:
| Disposition | Meaning | Licensed by |
| --- | --- | --- |
| `VALID` | Violates a §8 property via an in-scope §7 adversary using an in-scope §6 input. | §8, §6, §7 |
| `VALID-HARDENING` | No §8 property violated, but a §11 misuse pattern can be made harder to fall into by code change. Typically no CVE. | §11 |
| `OUT-OF-MODEL: trusted-input` | Requires attacker control of a §6 parameter the model marks trusted (caller-supplied `Document` / `Element`, caller-supplied `baseUri`, caller-supplied `URIResolver`, JVM system property, etc.). | §6 |
| `OUT-OF-MODEL: adversary-not-in-scope` | Requires a §7 actor the model excludes (in-process caller, hostile `URIResolver`, operator). | §7 |
| `OUT-OF-MODEL: unsupported-component` | Lands in `w3c-testcases/`, `*/src/test/`, `etc/`, `xmlschema-bundle-test/`. | §3 items 4, 8 |
| `OUT-OF-MODEL: non-default-build` | Only manifests under a §5a configuration the maintainer rules dev/test (e.g. an unsafe custom `URIResolver`). | §5a |
| `OUT-OF-MODEL: out-of-layer` | Concerns a *document* validation step delegated to `javax.xml.validation.Validator`, or a WSDL parser upstream. | §3 items 1–3 |
| `BY-DESIGN: property-disclaimed` | Concerns a §9 property the project explicitly does not provide (no SSRF defense, no guarantee of default DTD acceptance, no schema-size, imported-byte, or fetch-rate ceiling). | §9 |
| `KNOWN-NON-FINDING` | Matches a §11a recurring false positive. | §11a |
| `MODEL-GAP` | Cannot be cleanly routed to any of the above — triggers §12 model revision. | §12 |
## §14 Open questions for the maintainers
Every *(inferred)* tag in the body maps to one of these. Proposed
answers are inline; please confirm, correct, or strike.
### Wave 1 — security policy + meta
**Q1.** XMLSchema does not currently ship an in-repo `SECURITY.md`.
The de facto policy is "report via `https://www.apache.org/security/`".
Should the project (a) adopt a `SECURITY.md` that names a supported-
branch matrix (proposed), (b) leave reporting to the foundation page
only, or (c) defer to the Webservices PMC's umbrella policy? *(meta)*
**Q2.** Confirm that XMLSchema's threat model treats the project as
**a schema-modeling library that performs network IO when resolving
imports**, not a generic XML parser (proposed: **yes**). *(maps to §2)*
**Q3.** `xmlschema-walker.XmlSchemaElementValidator` — proposed
position is "tooling helper, not a claimed-conformant document
validator". Confirm? *(maps to §3 item 1, §9 false-friend, §11)*
### Wave 2 — XXE / DTD posture (highest leverage)
**Q4.** When `read(Document)` / `read(Element)` is the entry point,
proposed position is "the caller's DOM was already parsed; XMLSchema
makes no XXE claim about it" (`OUT-OF-MODEL: trusted-input`). Confirm?
*(maps to §3 item 5, §13)*
**Q5.** When the URI resolver follows an `xs:import schemaLocation`,
proposed position is "what the remote host returns is parsed by the
internal XMLSchema parser path; the *fetch* itself is the
attacker-influenced action and §9 disclaims SSRF defense" (`§9`).
Confirm? *(maps to §3 item 6, §9)*
**Q6.** **DTD compatibility posture.** XMLSchema now rejects DOCTYPE
declarations by default on the internal schema parser, disables external
DTD/entity resolution, and offers
`org.apache.ws.commons.schema.allowDTD=true` to accept DTD-bearing schema
documents while keeping external resolution disabled. Confirm that this is
the supported posture for untrusted schema bytes. *(maps to §5a, §8 P2,
§9, §10, §11a)*
### Wave 3 — URI resolver / SSRF
**Q7.** Confirm that XMLSchema does *not* sanitize `schemaLocation`
when it begins with `file://`, `jar:`, etc. (proposed: no sanitization;
operator's `URIResolver` is the gate). *(maps to §5, §11a)*
**Q8.** XMLSchema has no documented bound on schema-document size,
imported bytes, or fetch rate. Import/include resolution does have
configurable defaults of 64 levels and 1000 resolved schema documents per
top-level read. The caller remains responsible for additional deployment-
specific resource budgets. *(maps to §5, §9, §10 item 4)*
**Q9.** `org.apache.ws.commons.schema.extension_registry` system
property: confirm that production deployments are expected to set
it (if at all) at JVM startup from a trusted source — i.e. an
untrusted-actor-set value is `OUT-OF-MODEL: trusted-input` (proposed).
*(maps to §5a, §11)*
**Q10.** Negative-side inventory in §5: XMLSchema opens **no**
sockets *other than what the JDK URL handler does when following an
import*; spawns **no** processes; installs **no** signal handlers;
reads **only** the documented system property; writes **nothing** of
its own initiative. Confirm? *(maps to §5)*
**Q11.** Build-time variants: confirm there are no compile-time feature
toggles; the security envelope is shaped only by runtime extension
points (proposed). *(maps to §5a)*
**Q12.** **The big URI-resolver question.** The bundled
`DefaultURIResolver` follows `http://` / `https://` / `file://` /
`jar:` URLs without filtering. Is this:
- (a) "Supported production posture" — a report that an attacker
schema's `<xs:import schemaLocation='http://attacker/'/>` triggered
a fetch is `VALID`?
- (b) "Dev/test default; operators are documented as required to
install a restricting resolver per §10" — same report is
`OUT-OF-MODEL: non-default-build`?
Proposed: **(b)** with a clarification in `README.txt` and/or
`SECURITY.md` that production deployments handling untrusted schema
bytes must install a restricting `URIResolver`. *(maps to §5a, §9,
§10 item 1, §11a, §13)*
### Wave 4 — adversary model, edge cases
**Q13.** Network attacker on `http://` import fetches: proposed
position is "operator is documented as required to use `https://`
or a restricting resolver; TLS validity is the JDK URL handler's
concern". Confirm? *(maps to §7)*
**Q14.** Co-tenant in shared JVM and side-channel observers: out of
scope (proposed)? *(maps to §7)*
**Q15.** §8 P1 (memory safety on parse): proposed wording "any
`RuntimeException` outside the documented `XmlSchemaException`/
`ParserConfigurationException`/`IOException`/`SAXException` family is
`VALID-HARDENING`". Confirm? *(maps to §8 P1)*
**Q16.** §8 P3 (round-trip parse → model → serialize consistency):
do you claim this as a security property, or only as a correctness
one? Proposed: correctness-only unless the divergence creates a
security-meaningful downstream misinterpretation, in which case it is
a `VALID-HARDENING`. *(maps to §8 P3)*
**Q17.** §8 P4 (walker deterministic visit order): is the visit order
documented? Proposed: correctness-only. *(maps to §8 P4)*
**Q18.** `setBaseUri(...)` semantics: if an `<xs:import
schemaLocation='http://absolute/'/>` is encountered, the base URI is
ignored. Confirm? *(maps to §9 false-friend)*
**Q19.** Threading model: is `XmlSchemaCollection` documented as
thread-safe? Proposed: not thread-safe; callers synchronize. *(maps to
§11)*
### Wave 5 — coexistence & publication
**Q20.** This document should be hosted in-repo at
`docs/security/threat-model.md` (proposed) or on
`ws.apache.org/xmlschema/`? *(meta)*
**Q21.** §11a known-non-findings is thin (~11 patterns). Could the
XMLSchema PMC populate from the JIRA "not a bug" / "wontfix"
closures (`XMLSCHEMA-*` tickets)? Concrete asks: 3–5 patterns the PMC
sees recur in inbound reports. *(meta — §11a)*
**Q22.** What kind of change to XMLSchema should trigger a revision
(proposed list in §12 — confirm or correct)? *(meta — §12)*
**Q23.** `xmlschema-walker` cycle handling: should rejection of cyclic
type derivation, substitution-group, model-group, and attribute-group
expansions be treated as a claimed medium-severity availability property
for attacker-controlled schemas? Proposed: **yes**; malformed but
parseable cycles must terminate with `XmlSchemaException`, while legal
recursive content through element declarations remains supported. *(maps
to §4, §6, §8 P5)*
---
## Appendix: SECURITY.md / website → §x back-map
XMLSchema ships a `SECURITY.md` that points vulnerability reporters to
the Apache Software Foundation security process. The threat-model sources
are the in-repo `README.txt`, the `RELEASE-NOTE.txt`, `SECURITY.md`, and
the JavaDoc / source comments. The project website is
<https://ws.apache.org/xmlschema/>.
| Source | Claim | Lands in |
| --- | --- | --- |
| `SECURITY.md` | vulnerability reports go through the Apache Software Foundation security process and this threat model documents scope / triage | §1 |
| `README.txt` | "lightweight schema object model that can be used to manipulate and generate XML schema representations" | §1, §2 intended use |
| `RELEASE-NOTE.txt` (2.3.0) | Java 17 minimum, Java 7 dropped | §5 environment |
| `xmlschema-core/src/main/java/org/apache/ws/commons/schema/XmlSchemaCollection.java` line 361 | `org.apache.ws.commons.schema.extension_registry` system property loaded via `Class.forName` | §5a, §6, §11 |
| `xmlschema-core/src/main/java/org/apache/ws/commons/schema/SchemaBuilder.java` | `org.apache.ws.commons.schema.maxNestingDepth` structural descent limit | §5, §5a, §6, §8 P6 |
| `XmlSchemaCollection.java` | internal parser sets `FEATURE_SECURE_PROCESSING`, rejects DOCTYPE by default, disables external DTD/entity resolution, and honors `org.apache.ws.commons.schema.allowDTD` for compatibility | §5a, §8 P2 |
| `XmlSchemaCollection.java` line 745 | `AccessController.doPrivileged` wrapper for the SAX parse | §5 |
| `XmlSchema.java` | serializer `TransformerFactory` sets `FEATURE_SECURE_PROCESSING` and disables external DTD/stylesheet access where supported | §5a, §8 P2 |
| `xmlschema-core/src/main/java/.../resolver/DefaultURIResolver.java` | URL composed from `baseUri` + `schemaLocation`; no filtering | §3 item 7, §9 SSRF disclaim, §10 item 1, §11 first bullet |
| `xmlschema-core/src/main/java/.../resolver/URIResolver.java` | Resolver interface — caller-pluggable | §2 caller-roles, §10 item 1 |
| `xmlschema-walker/src/main/java/.../docpath/DomBuilderFromSax.java` line 81 | `factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, TRUE)` | §5a, §8 P2 |
| `xmlschema-walker/src/main/java/.../docpath/XmlSchemaPathFinder.java` | Configurable per-document limits on decision points and replayed events | §4, §5a, §6, §12 |
| `xmlschema-walker/src/main/java/.../walker/XmlSchemaWalker.java` and `XmlSchemaScope.java` | Active-path cycle detection for schema expansion | §4, §6, §8 P5 |