This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ws-xmlschema.git
The following commit(s) were added to refs/heads/master by this push:
new 7c41ddde Allow redirects again for the DefaultURIResolver
7c41ddde is described below
commit 7c41ddde105e9f08442cb803e0657e5d76fe0f28
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Thu Sep 17 10:59:51 2026 +0100
Allow redirects again for the DefaultURIResolver
---
README.txt | 12 +++++++-----
THREAT-MODEL.md | 21 +++++++++++++++++++--
.../commons/schema/resolver/DefaultURIResolver.java | 4 ----
3 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/README.txt b/README.txt
index 4c780598..0d002be6 100644
--- a/README.txt
+++ b/README.txt
@@ -137,11 +137,13 @@ For example, set a limit with:
falls back to any schema already registered for that namespace; a
resolver that throws rejects the read outright.
- Note that a host allowlist cannot be enforced from inside a URIResolver:
- it returns a system ID and the JDK opens the connection, following HTTP
- redirects without consulting the resolver again. A resolver that must
- restrict destinations has to fetch the bytes itself and return an
- InputSource wrapping the stream.
+ Note that a host allowlist cannot be enforced simply by inspecting the
+ location: whoever opens the connection follows HTTP redirects, and a
+ redirect can move the fetch to another host. A resolver that must
+ restrict destinations has to open the connection itself, with redirect
+ following disabled, and re-check each hop. The bundled resolver does
+ open network connections itself, to bound them, but applies no host
+ policy and leaves redirects to the JDK.
See THREAT-MODEL.md section 10 for the full list of downstream
responsibilities.
diff --git a/THREAT-MODEL.md b/THREAT-MODEL.md
index 9bf45b3f..99f3410e 100644
--- a/THREAT-MODEL.md
+++ b/THREAT-MODEL.md
@@ -176,8 +176,12 @@ A finding is in-model only if it reaches a row marked
**yes**.
for SSRF / cross-origin fetch when the input schema is attacker-
controlled and contains an `xs:import schemaLocation="…"`. The
bundled resolver checks the effective scheme against an allowlist and
- then returns an `InputSource`; the JDK fetches it on `parse()`, and
- follows any HTTP redirects itself without consulting the resolver.
+ then returns an `InputSource`. A local location keeps the
+ system-id-only form and the parser opens it; a network location gets a
+ byte stream the resolver opens on first read, under per-fetch timeout
+ and size bounds. Redirects are the JDK's: it will not follow one that
+ changes scheme, and follows a same-scheme one without consulting the
+ resolver again.
- **`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
@@ -727,6 +731,19 @@ Revise this document when any of the following lands:
rule as first written: it tested only the URI authority, so
`file:////host/share/x.xsd`, which parses with no authority and
carries the host in its path instead, was not caught.
+- **2026-09-17** — "Place default limits on read timeouts + size on
+ remote schemas" (#152) is a revision trigger under the first bullet
+ above: a network location is now fetched through a stream the resolver
+ opens, bounded by connect, read and total-fetch timeouts and by a byte
+ ceiling, all operator-tunable (§5a). §4 reachability is updated. That
+ commit also disabled redirect following, which was reverted on review:
+ the JDK never followed a scheme-changing redirect, so no `http` to
+ `https` upgrade was lost by it, but same-scheme redirects did work
+ before and schemas do move. With no host policy applied there is
+ nothing a redirect bypasses, so following them costs nothing and
+ refusing them broke moved schemas. A host allowlist would have to
+ re-check each hop, which is why §9 still records it as unenforceable
+ at this boundary.
- **2026-09-16** — "Fix up DTD handling" (#147) changed the default
parser DTD posture, a revision trigger under the second bullet above:
external DTD and external entity resolution are now disabled
diff --git
a/xmlschema-core/src/main/java/org/apache/ws/commons/schema/resolver/DefaultURIResolver.java
b/xmlschema-core/src/main/java/org/apache/ws/commons/schema/resolver/DefaultURIResolver.java
index 06d6f2c5..91558b9a 100644
---
a/xmlschema-core/src/main/java/org/apache/ws/commons/schema/resolver/DefaultURIResolver.java
+++
b/xmlschema-core/src/main/java/org/apache/ws/commons/schema/resolver/DefaultURIResolver.java
@@ -21,7 +21,6 @@ package org.apache.ws.commons.schema.resolver;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -215,9 +214,6 @@ public class DefaultURIResolver implements
CollectionURIResolver {
connection.setDoInput(true);
connection.setConnectTimeout(toIntMillis(connectTimeoutMillis));
connection.setReadTimeout(toIntMillis(readTimeoutMillis));
- if (connection instanceof HttpURLConnection) {
-
((HttpURLConnection)connection).setInstanceFollowRedirects(false);
- }
deadlineNanos = System.nanoTime() + maxFetchMillis * 1000000L;
// A declared length is a courtesy: it is absent for a chunked
response and is in any
// case whatever the host chose to claim. The running count below
is the real limit.