This is an automated email from the ASF dual-hosted git repository.

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-core.git

commit d93657ea86bcc3d27010c29947855f91da94a405
Author: Robert Lazarski <[email protected]>
AuthorDate: Mon May 18 08:00:15 2026 -1000

    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) <[email protected]>
---
 .../description/WSDLToAxisServiceBuilder.java      | 37 +++++++++++++---------
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git 
a/modules/kernel/src/org/apache/axis2/description/WSDLToAxisServiceBuilder.java 
b/modules/kernel/src/org/apache/axis2/description/WSDLToAxisServiceBuilder.java
index b271b069ce..cc38f14f87 100644
--- 
a/modules/kernel/src/org/apache/axis2/description/WSDLToAxisServiceBuilder.java
+++ 
b/modules/kernel/src/org/apache/axis2/description/WSDLToAxisServiceBuilder.java
@@ -154,24 +154,31 @@ public abstract class WSDLToAxisServiceBuilder {
                             delegate = new 
org.apache.ws.commons.schema.resolver.DefaultURIResolver();
                     public org.xml.sax.InputSource resolveEntity(
                             String ns, String loc, String base) {
-                        // Resolve against base URI before checking —
-                        // a relative loc with a remote base must be caught
-                        String resolved = loc;
-                        if (base != null && loc != null) {
+                        // Allowlist: only permit relative paths resolved
+                        // against the base URI. Block all absolute URIs
+                        // (http, https, ftp, file, jar, etc.) to prevent
+                        // both SSRF and LFI. Co-packaged schemas in .aar
+                        // deployments use relative paths and are safe.
+                        if (loc != null) {
+                            String resolved = loc;
+                            if (base != null) {
+                                try {
+                                    resolved = java.net.URI.create(base)
+                                            .resolve(loc).toString();
+                                } catch (IllegalArgumentException ignored) {
+                                }
+                            }
                             try {
-                                resolved = 
java.net.URI.create(base).resolve(loc).toString();
-                            } catch (IllegalArgumentException ignored) {
+                                java.net.URI uri = new java.net.URI(resolved);
+                                if (uri.isAbsolute()) {
+                                    throw new RuntimeException(
+                                        "Absolute schemaLocation blocked: "
+                                        + resolved + " (use setCustomResolver"
+                                        + " to opt in)");
+                                }
+                            } catch (java.net.URISyntaxException ignored) {
                             }
                         }
-                        if (resolved != null
-                                && (resolved.regionMatches(true, 0, "http:", 
0, 5)
-                                 || resolved.regionMatches(true, 0, "https:", 
0, 6)
-                                 || resolved.regionMatches(true, 0, "ftp:", 0, 
4)
-                                 || resolved.regionMatches(true, 0, "jar:", 0, 
4))) {
-                            throw new RuntimeException(
-                                    "Remote schemaLocation blocked: " + 
resolved
-                                    + " (use setCustomResolver to opt in)");
-                        }
                         return delegate.resolveEntity(ns, loc, base);
                     }
                 });

Reply via email to