diff --git a/src/main/java/org/apache/xmlbeans/impl/schema/FileResourceLoader.java b/src/main/java/org/apache/xmlbeans/impl/schema/FileResourceLoader.java index 556f4c4ca..65fe9a278 100644 --- a/src/main/java/org/apache/xmlbeans/impl/schema/FileResourceLoader.java +++ b/src/main/java/org/apache/xmlbeans/impl/schema/FileResourceLoader.java @@ -52,7 +52,15 @@ public InputStream getResourceAsStream(String resourceName) } else { - return Files.newInputStream(new File(_directory, resourceName).toPath()); + File file = new File(_directory, resourceName); + // A resource name is built from an attacker-controllable handle read out of a + // compiled .xsb; a handle containing "../" would otherwise let the resolved path + // escape the resource directory and read arbitrary .xsb-suffixed files on disk. + if (!isContainedIn(file, _directory)) + { + return null; + } + return Files.newInputStream(file.toPath()); } } catch (IOException e) @@ -61,6 +69,20 @@ public InputStream getResourceAsStream(String resourceName) } } + private static boolean isContainedIn(File file, File directory) + { + try + { + String dirPath = directory.getCanonicalPath() + File.separator; + String filePath = file.getCanonicalPath(); + return filePath.startsWith(dirPath); + } + catch (IOException e) + { + return false; + } + } + public void close() { if (_zipfile != null)