Skip to content

Commit d93657e

Browse files
Switch getXMLSchema() resolver from blocklist to allowlist
Gemini review identified that blocking specific schemes (http, https, ftp, jar) while allowing file:// leaves a Local File Inclusion (LFI) vector. Switch to allowlist approach: block ALL absolute URIs in the default restrictive resolver. Only relative paths (resolved against the document base URI) are permitted. This prevents SSRF, LFI, and any future bypass via exotic URI schemes. Co-packaged schemas in .aar/.war deployments use relative paths and are unaffected. Applications needing absolute URI resolution can supply their own resolver via setCustomResolver(). 404 kernel tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0afbb74 commit d93657e

1 file changed

Lines changed: 22 additions & 15 deletions

File tree

modules/kernel/src/org/apache/axis2/description/WSDLToAxisServiceBuilder.java

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,24 +154,31 @@ protected XmlSchema getXMLSchema(Element element, String baseUri) {
154154
delegate = new org.apache.ws.commons.schema.resolver.DefaultURIResolver();
155155
public org.xml.sax.InputSource resolveEntity(
156156
String ns, String loc, String base) {
157-
// Resolve against base URI before checking —
158-
// a relative loc with a remote base must be caught
159-
String resolved = loc;
160-
if (base != null && loc != null) {
157+
// Allowlist: only permit relative paths resolved
158+
// against the base URI. Block all absolute URIs
159+
// (http, https, ftp, file, jar, etc.) to prevent
160+
// both SSRF and LFI. Co-packaged schemas in .aar
161+
// deployments use relative paths and are safe.
162+
if (loc != null) {
163+
String resolved = loc;
164+
if (base != null) {
165+
try {
166+
resolved = java.net.URI.create(base)
167+
.resolve(loc).toString();
168+
} catch (IllegalArgumentException ignored) {
169+
}
170+
}
161171
try {
162-
resolved = java.net.URI.create(base).resolve(loc).toString();
163-
} catch (IllegalArgumentException ignored) {
172+
java.net.URI uri = new java.net.URI(resolved);
173+
if (uri.isAbsolute()) {
174+
throw new RuntimeException(
175+
"Absolute schemaLocation blocked: "
176+
+ resolved + " (use setCustomResolver"
177+
+ " to opt in)");
178+
}
179+
} catch (java.net.URISyntaxException ignored) {
164180
}
165181
}
166-
if (resolved != null
167-
&& (resolved.regionMatches(true, 0, "http:", 0, 5)
168-
|| resolved.regionMatches(true, 0, "https:", 0, 6)
169-
|| resolved.regionMatches(true, 0, "ftp:", 0, 4)
170-
|| resolved.regionMatches(true, 0, "jar:", 0, 4))) {
171-
throw new RuntimeException(
172-
"Remote schemaLocation blocked: " + resolved
173-
+ " (use setCustomResolver to opt in)");
174-
}
175182
return delegate.resolveEntity(ns, loc, base);
176183
}
177184
});

0 commit comments

Comments
 (0)