You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ff...@apache.org on 2018/01/13 11:06:34 UTC

[cxf] branch 3.1.x-fixes updated: [CXF-7597] Fix suspicious class loader findResource calls when resolving absolute URIs

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

ffang pushed a commit to branch 3.1.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/3.1.x-fixes by this push:
     new 95815ec  [CXF-7597] Fix suspicious class loader findResource calls when resolving absolute URIs
95815ec is described below

commit 95815eca4b8e301805a09ce7cff18372c6106146
Author: Pavol Mederly <me...@evolveum.com>
AuthorDate: Thu Dec 21 18:50:46 2017 +0100

    [CXF-7597] Fix suspicious class loader findResource calls when resolving absolute URIs
    
    (cherry picked from commit 44d99924db52f2a4b5bdacc41bd83b81bffb8cb4)
    
    Conflicts:
    	core/src/main/java/org/apache/cxf/resource/URIResolver.java
    	core/src/test/java/org/apache/cxf/resource/URIResolverTest.java
---
 .../java/org/apache/cxf/resource/URIResolver.java  |  16 ++-
 .../org/apache/cxf/resource/URIResolverTest.java   | 117 +++++++++++++++++++--
 2 files changed, 120 insertions(+), 13 deletions(-)

diff --git a/core/src/main/java/org/apache/cxf/resource/URIResolver.java b/core/src/main/java/org/apache/cxf/resource/URIResolver.java
index ed22767..6654d41 100644
--- a/core/src/main/java/org/apache/cxf/resource/URIResolver.java
+++ b/core/src/main/java/org/apache/cxf/resource/URIResolver.java
@@ -83,7 +83,8 @@ public class URIResolver {
         } else if (baseUriStr != null 
             && (baseUriStr.startsWith("jar:") 
                 || baseUriStr.startsWith("zip:")
-                || baseUriStr.startsWith("wsjar:"))) {
+                || baseUriStr.startsWith("wsjar:"))
+            && !isAbsolute(uriStr)) {
             tryArchive(baseUriStr, uriStr);
         } else if (uriStr.startsWith("jar:") 
             || uriStr.startsWith("zip:")
@@ -112,7 +113,8 @@ public class URIResolver {
         } else if (baseUriStr != null 
             && (baseUriStr.startsWith("jar:") 
                 || baseUriStr.startsWith("zip:")
-                || baseUriStr.startsWith("wsjar:"))) {
+                || baseUriStr.startsWith("wsjar:"))
+            && !isAbsolute(uriStr)) {
             tryArchive(baseUriStr, uriStr);
         } else if (uriStr.startsWith("jar:") 
             || uriStr.startsWith("zip:")
@@ -123,8 +125,14 @@ public class URIResolver {
         }
     }
 
-    
-    
+    private boolean isAbsolute(String uriStr) {
+        try {
+            return new URI(uriStr).isAbsolute();
+        } catch (URISyntaxException e) {
+            return false;
+        }
+    }
+
     private void tryFileSystem(String baseUriStr, String uriStr) throws IOException, MalformedURLException {
         try {
             URI relative;
diff --git a/core/src/test/java/org/apache/cxf/resource/URIResolverTest.java b/core/src/test/java/org/apache/cxf/resource/URIResolverTest.java
index 5997abb..486ea1c 100644
--- a/core/src/test/java/org/apache/cxf/resource/URIResolverTest.java
+++ b/core/src/test/java/org/apache/cxf/resource/URIResolverTest.java
@@ -32,8 +32,9 @@ public class URIResolverTest extends Assert {
     private URIResolver uriResolver;
     
     private URL resourceURL = getClass().getResource("resources/helloworld.bpr");
-    
-    
+
+    private Throwable checkingThreadThrowable;      // assumes single-thread test execution
+
     @Test
     public void testJARProtocol() throws Exception {
         uriResolver = new URIResolver();
@@ -63,6 +64,9 @@ public class URIResolverTest extends Assert {
             
         }       
         assertEquals(IOUtils.newStringFromBytes(barray), IOUtils.newStringFromBytes(barray2));
+
+        resolveWithCheckingClassloader(uriResolver, "baseUriStr", uriStr, null);
+        resolveWithCheckingClassloaderInConstructor("baseUriStr", uriStr, null);
     }
 
     @Test
@@ -84,10 +88,32 @@ public class URIResolverTest extends Assert {
         uriResolver.resolve(uriStr, "hello_world_2.wsdl", null);
         
         InputStream is3 = uriResolver.getInputStream();
-        assertNotNull(is3); 
+        assertNotNull(is3);
+
+        resolveWithCheckingClassloader(uriResolver, uriStr, "hello_world_2.wsdl", null);
+        resolveWithCheckingClassloaderInConstructor(uriStr, "hello_world_2.wsdl", null);
     }
-    
-    
+
+    @Test
+    public void testJARResolveBaseAndAbsolute() throws Exception {
+        uriResolver = new URIResolver();
+
+        String baseUriStr = "jar:" + resourceURL.toString() + "!/wsdl/hello_world.wsdl";
+
+        URL jarURL = new URL(baseUriStr);
+        InputStream is = jarURL.openStream();
+        assertNotNull(is);
+
+        String uriStr = "jar:" + resourceURL.toString() + "!/wsdl/hello_world_2.wsdl";
+
+        URL jarURL2 = new URL(uriStr);
+        InputStream is2 = jarURL2.openStream();
+        assertNotNull(is2);
+
+        resolveWithCheckingClassloader(uriResolver, baseUriStr, uriStr, null);
+        resolveWithCheckingClassloaderInConstructor(baseUriStr, uriStr, null);
+    }
+
     @Test
     public void testResolveRelativeFile() throws Exception {
         URIResolver wsdlResolver = new URIResolver();
@@ -104,12 +130,15 @@ public class URIResolverTest extends Assert {
         URIResolver xsdResolver = new URIResolver();
         xsdResolver.resolve(baseUri, schemaLocation, this.getClass());
         assertNotNull(xsdResolver.getInputStream());
-        
+        resolveWithCheckingClassloader(xsdResolver, baseUri, schemaLocation, this.getClass());
+        resolveWithCheckingClassloaderInConstructor(baseUri, schemaLocation, this.getClass());
+
         // resolve the schema using relative location with base uri fragment
         xsdResolver = new URIResolver();
         xsdResolver.resolve(baseUri + "#type2", schemaLocation, this.getClass());
         assertNotNull(xsdResolver.getInputStream());
-        
+        resolveWithCheckingClassloader(xsdResolver, baseUri + "#type2", schemaLocation, this.getClass());
+        resolveWithCheckingClassloaderInConstructor(baseUri + "#type2", schemaLocation, this.getClass());
     }
     
     @Test
@@ -128,12 +157,15 @@ public class URIResolverTest extends Assert {
         URIResolver xsdResolver = new URIResolver();
         xsdResolver.resolve(baseUri, schemaLocation, this.getClass());
         assertNotNull(xsdResolver.getInputStream());
-        
+        resolveWithCheckingClassloader(xsdResolver, baseUri, schemaLocation, this.getClass());
+        resolveWithCheckingClassloaderInConstructor(baseUri, schemaLocation, this.getClass());
+
         // resolve the schema using relative location with base uri fragment
         xsdResolver = new URIResolver();
         xsdResolver.resolve(baseUri + "#type2", schemaLocation, this.getClass());
         assertNotNull(xsdResolver.getInputStream());
-        
+        resolveWithCheckingClassloader(xsdResolver, baseUri + "#type2", schemaLocation, this.getClass());
+        resolveWithCheckingClassloaderInConstructor(baseUri + "#type2", schemaLocation, this.getClass());
     }
 
     @Test
@@ -142,6 +174,8 @@ public class URIResolverTest extends Assert {
         // resolve the wsdl
         wsdlResolver.resolve(null, "wsdl/folder with spaces/foo.wsdl", this.getClass());
         assertTrue(wsdlResolver.isResolved());
+        resolveWithCheckingClassloader(wsdlResolver, null, "wsdl/folder with spaces/foo.wsdl", this.getClass());
+        resolveWithCheckingClassloaderInConstructor(null, "wsdl/folder with spaces/foo.wsdl", this.getClass());
     }
     
     @Test
@@ -150,5 +184,70 @@ public class URIResolverTest extends Assert {
         // resolve the wsdl
         wsdlResolver.resolve(null, "wsdl/folder%20with%20spaces/foo.wsdl", this.getClass());
         assertTrue(wsdlResolver.isResolved());
+        resolveWithCheckingClassloader(wsdlResolver, null, "wsdl/folder%20with%20spaces/foo.wsdl", this.getClass());
+        resolveWithCheckingClassloaderInConstructor(null, "wsdl/folder%20with%20spaces/foo.wsdl", this.getClass());
+    }
+
+    private void resolveWithCheckingClassloader(final URIResolver resolver, 
+            final String baseUriStr, final String uriStr,
+            final Class<?> callingCls) throws InterruptedException {
+        checkingThreadThrowable = null;
+        Runnable operation = new Runnable() {
+            
+            public void run() {
+                try {
+                    resolver.resolve(baseUriStr, uriStr, callingCls);
+                } catch (Throwable t) {
+                    checkingThreadThrowable = t;
+                }
+                assertNotNull(resolver.getInputStream());
+            }
+        };
+        Thread thread = new Thread(operation);
+        thread.setContextClassLoader(new CheckingClassLoader(this.getClass().getClassLoader()));
+        thread.start();
+        thread.join(10000);
+        assertFalse("resolve operation did not finish in time", thread.isAlive());
+        assertNull(checkingThreadThrowable);
+    }
+
+    private void resolveWithCheckingClassloaderInConstructor(final String baseUriStr, 
+            final String uriStr, final Class<?> callingCls)
+            throws InterruptedException {
+        checkingThreadThrowable = null;
+        Runnable operation = new Runnable() {
+
+            public void run() {
+                URIResolver resolver = null;
+                try {
+                    resolver = new URIResolver(baseUriStr, uriStr, callingCls);
+                } catch (Throwable t) {
+                    checkingThreadThrowable = t;
+                }
+                if (resolver != null) {
+                    assertNotNull(resolver.getInputStream());
+                }
+            }
+        };
+        Thread thread = new Thread(operation);
+        thread.setContextClassLoader(new CheckingClassLoader(this.getClass().getClassLoader()));
+        thread.start();
+        thread.join(10000);
+        assertFalse("resolve operation did not finish in time", thread.isAlive());
+        assertNull(checkingThreadThrowable);
+    }
+
+    static class CheckingClassLoader extends ClassLoader {
+        CheckingClassLoader(ClassLoader parent) {
+            super(parent);
+        }
+
+        @Override
+        protected URL findResource(String name) {
+            if (name != null && name.startsWith("jar:file:")) {
+                throw new AssertionError("Suspicious resource name: " + name);
+            }
+            return super.findResource(name);
+        }
     }
 }

-- 
To stop receiving notification emails like this one, please contact
['"commits@cxf.apache.org" <co...@cxf.apache.org>'].