You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by co...@apache.org on 2021/09/02 08:20:22 UTC

[santuario-xml-security-java] 01/01: SANTUARIO-577 - Introduce a system property to control if file/http references are allowed from an unsigned context

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

coheigea pushed a commit to branch SANTUARIO-577
in repository https://gitbox.apache.org/repos/asf/santuario-xml-security-java.git

commit dd16c0a9ace2051dfc45f2375d56db5c08fb0310
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Thu Sep 2 09:19:56 2021 +0100

    SANTUARIO-577 - Introduce a system property to control if file/http references are allowed from an unsigned context
---
 .../xml/security/encryption/XMLCipherInput.java    |  9 ++++-
 .../implementations/KeyInfoReferenceResolver.java  |  9 ++++-
 .../implementations/RetrievalMethodResolver.java   | 17 +++++++---
 .../utils/resolver/ResourceResolverContext.java    | 14 ++++++++
 .../security/test/dom/interop/BaltimoreTest.java   |  2 ++
 .../dom/utils/resolver/ResourceResolverTest.java   | 38 ++++++++++++++++++++++
 6 files changed, 82 insertions(+), 7 deletions(-)

diff --git a/src/main/java/org/apache/xml/security/encryption/XMLCipherInput.java b/src/main/java/org/apache/xml/security/encryption/XMLCipherInput.java
index 68598f7..28f5c26 100644
--- a/src/main/java/org/apache/xml/security/encryption/XMLCipherInput.java
+++ b/src/main/java/org/apache/xml/security/encryption/XMLCipherInput.java
@@ -115,7 +115,14 @@ public class XMLCipherInput {
             try {
                 ResourceResolverContext resolverContext =
                     new ResourceResolverContext(uriAttr, null, secureValidation);
-                input = ResourceResolver.resolve(resolverContext);
+                if (resolverContext.isSafeURIToResolve()) {
+                    input = ResourceResolver.resolve(resolverContext);
+                } else {
+                    String uriToResolve = uriAttr != null ? uriAttr.getValue() : null;
+                    Object[] exArgs = {uriToResolve != null ? uriToResolve : "null", null};
+
+                    throw new ResourceResolverException("utils.resolver.noClass", exArgs, uriToResolve, null);
+                }
             } catch (ResourceResolverException ex) {
                 throw new XMLEncryptionException(ex);
             }
diff --git a/src/main/java/org/apache/xml/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java b/src/main/java/org/apache/xml/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java
index 9641632..ae56256 100644
--- a/src/main/java/org/apache/xml/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java
+++ b/src/main/java/org/apache/xml/security/keys/keyresolver/implementations/KeyInfoReferenceResolver.java
@@ -39,6 +39,7 @@ import org.apache.xml.security.utils.Constants;
 import org.apache.xml.security.utils.XMLUtils;
 import org.apache.xml.security.utils.resolver.ResourceResolver;
 import org.apache.xml.security.utils.resolver.ResourceResolverContext;
+import org.apache.xml.security.utils.resolver.ResourceResolverException;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
@@ -203,7 +204,13 @@ public class KeyInfoReferenceResolver extends KeyResolverSpi {
     private XMLSignatureInput resolveInput(Attr uri, String baseURI, boolean secureValidation)
         throws XMLSecurityException {
         ResourceResolverContext resContext = new ResourceResolverContext(uri, baseURI, secureValidation);
-        return ResourceResolver.resolve(resContext);
+        if (resContext.isSafeURIToResolve()) {
+            return ResourceResolver.resolve(resContext);
+        }
+        String uriToResolve = uri != null ? uri.getValue() : null;
+        Object[] exArgs = { uriToResolve != null ? uriToResolve : "null", baseURI };
+
+        throw new ResourceResolverException("utils.resolver.noClass", exArgs, uriToResolve, baseURI);
     }
 
     /**
diff --git a/src/main/java/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java b/src/main/java/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java
index aba90e1..d7c951a 100644
--- a/src/main/java/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java
+++ b/src/main/java/org/apache/xml/security/keys/keyresolver/implementations/RetrievalMethodResolver.java
@@ -47,6 +47,7 @@ import org.apache.xml.security.utils.Constants;
 import org.apache.xml.security.utils.XMLUtils;
 import org.apache.xml.security.utils.resolver.ResourceResolver;
 import org.apache.xml.security.utils.resolver.ResourceResolverContext;
+import org.apache.xml.security.utils.resolver.ResourceResolverException;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -254,12 +255,18 @@ public class RetrievalMethodResolver extends KeyResolverSpi {
         // Apply the transforms
         Transforms transforms = rm.getTransforms();
         ResourceResolverContext resContext = new ResourceResolverContext(uri, baseURI, secureValidation);
-        XMLSignatureInput resource = ResourceResolver.resolve(resContext);
-        if (transforms != null) {
-            LOG.debug("We have Transforms");
-            resource = transforms.performTransforms(resource);
+        if (resContext.isSafeURIToResolve()) {
+            XMLSignatureInput resource = ResourceResolver.resolve(resContext);
+            if (transforms != null) {
+                LOG.debug("We have Transforms");
+                resource = transforms.performTransforms(resource);
+            }
+            return resource;
         }
-        return resource;
+        String uriToResolve = uri != null ? uri.getValue() : null;
+        Object[] exArgs = { uriToResolve != null ? uriToResolve : "null", baseURI };
+
+        throw new ResourceResolverException("utils.resolver.noClass", exArgs, uriToResolve, baseURI);
     }
 
     /** {@inheritDoc} */
diff --git a/src/main/java/org/apache/xml/security/utils/resolver/ResourceResolverContext.java b/src/main/java/org/apache/xml/security/utils/resolver/ResourceResolverContext.java
index f584401..5e76ded 100644
--- a/src/main/java/org/apache/xml/security/utils/resolver/ResourceResolverContext.java
+++ b/src/main/java/org/apache/xml/security/utils/resolver/ResourceResolverContext.java
@@ -18,6 +18,8 @@
  */
 package org.apache.xml.security.utils.resolver;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Collections;
 import java.util.Map;
 
@@ -25,6 +27,10 @@ import org.w3c.dom.Attr;
 
 public class ResourceResolverContext {
 
+    private static boolean allowUnsafeResourceResolving =
+            AccessController.doPrivileged(
+                    (PrivilegedAction<Boolean>) () -> Boolean.getBoolean("org.apache.xml.security.allowUnsafeResourceResolving"));
+
     private final Map<String, String> properties;
 
     public final String uriToResolve;
@@ -51,4 +57,12 @@ public class ResourceResolverContext {
         return properties;
     }
 
+    public boolean isSafeURIToResolve() {
+        if (allowUnsafeResourceResolving) {
+            return true;
+        }
+        boolean forbiddenURI = (uriToResolve != null && (uriToResolve.startsWith("file:") || uriToResolve.startsWith("http:")))
+                || (baseUri != null && (baseUri.startsWith("file:") || baseUri.startsWith("http:")));
+        return !forbiddenURI;
+    }
 }
diff --git a/src/test/java/org/apache/xml/security/test/dom/interop/BaltimoreTest.java b/src/test/java/org/apache/xml/security/test/dom/interop/BaltimoreTest.java
index 833ad72..555f041 100644
--- a/src/test/java/org/apache/xml/security/test/dom/interop/BaltimoreTest.java
+++ b/src/test/java/org/apache/xml/security/test/dom/interop/BaltimoreTest.java
@@ -52,6 +52,8 @@ public class BaltimoreTest extends InteropTestBase {
         "src/test/resources/ie/baltimore/merlin-examples/merlin-xmldsig-twenty-three/";
 
     static {
+        System.setProperty("org.apache.xml.security.allowUnsafeResourceResolving", "true");
+
         String basedir = System.getProperty("basedir");
         if(basedir != null && basedir.length() != 0) {
             merlinsDir15 = basedir + "/" + merlinsDir15;
diff --git a/src/test/java/org/apache/xml/security/test/dom/utils/resolver/ResourceResolverTest.java b/src/test/java/org/apache/xml/security/test/dom/utils/resolver/ResourceResolverTest.java
index 0a37b59..d07155f 100644
--- a/src/test/java/org/apache/xml/security/test/dom/utils/resolver/ResourceResolverTest.java
+++ b/src/test/java/org/apache/xml/security/test/dom/utils/resolver/ResourceResolverTest.java
@@ -28,7 +28,9 @@ import org.apache.xml.security.utils.resolver.implementations.ResolverLocalFiles
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
 /**
@@ -96,4 +98,40 @@ public class ResourceResolverTest {
         }
     }
 
+    @org.junit.jupiter.api.Test
+    public void testIsSafeURIToResolveFile() throws Exception {
+        Document doc = TestUtils.newDocument();
+        Attr uriAttr = doc.createAttribute("URI");
+        String basedir = System.getProperty("basedir");
+        String file = new File(basedir, "pom.xml").toURI().toString();
+        uriAttr.setValue(file);
+
+        ResourceResolverContext resolverContext =
+                new ResourceResolverContext(uriAttr, null, false);
+        assertFalse(resolverContext.isSafeURIToResolve());
+    }
+
+    @org.junit.jupiter.api.Test
+    public void testIsSafeURIToResolveHTTP() throws Exception {
+        Document doc = TestUtils.newDocument();
+        Attr uriAttr = doc.createAttribute("URI");
+        String basedir = System.getProperty("basedir");
+        uriAttr.setValue("http://www.apache.org");
+
+        ResourceResolverContext resolverContext =
+                new ResourceResolverContext(uriAttr, null, false);
+        assertFalse(resolverContext.isSafeURIToResolve());
+    }
+
+    @org.junit.jupiter.api.Test
+    public void testIsSafeURIToResolveLocalReference() throws Exception {
+        Document doc = TestUtils.newDocument();
+        Attr uriAttr = doc.createAttribute("URI");
+        String basedir = System.getProperty("basedir");
+        uriAttr.setValue("#1234");
+
+        ResourceResolverContext resolverContext =
+                new ResourceResolverContext(uriAttr, null, false);
+        assertTrue(resolverContext.isSafeURIToResolve());
+    }
 }
\ No newline at end of file