Skip to content

Commit

Permalink
Use java.nio.file.Path for consistent sub-directory checking
Browse files Browse the repository at this point in the history
  • Loading branch information
markt-asf committed Jan 20, 2021
1 parent de68139 commit 4785433
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 19 deletions.
2 changes: 1 addition & 1 deletion java/org/apache/catalina/servlets/DefaultServlet.java
Expand Up @@ -2137,7 +2137,7 @@ private File validateGlobalXsltFile(File base) {

// First check that the resulting path is under the provided base
try {
if (!candidate.getCanonicalPath().startsWith(base.getCanonicalPath())) {
if (!candidate.getCanonicalFile().toPath().startsWith(base.getCanonicalFile().toPath())) {
return null;
}
} catch (IOException ioe) {
Expand Down
2 changes: 1 addition & 1 deletion java/org/apache/catalina/session/FileStore.java
Expand Up @@ -351,7 +351,7 @@ private File file(String id) throws IOException {
File file = new File(storageDir, filename);

// Check the file is within the storage directory
if (!file.getCanonicalPath().startsWith(storageDir.getCanonicalPath())) {
if (!file.getCanonicalFile().toPath().startsWith(storageDir.getCanonicalFile().toPath())) {
log.warn(sm.getString("fileStore.invalid", file.getPath(), id));
return null;
}
Expand Down
3 changes: 2 additions & 1 deletion java/org/apache/catalina/startup/ContextConfig.java
Expand Up @@ -858,7 +858,8 @@ protected void fixDocBase() throws IOException {
String docBaseCanonical = docBaseAbsoluteFile.getCanonicalPath();

// Re-calculate now docBase is a canonical path
boolean docBaseCanonicalInAppBase = docBaseCanonical.startsWith(appBase.getPath() + File.separatorChar);
boolean docBaseCanonicalInAppBase =
docBaseAbsoluteFile.getCanonicalFile().toPath().startsWith(appBase.toPath());
String docBase;
if (docBaseCanonicalInAppBase) {
docBase = docBaseCanonical.substring(appBase.getPath().length());
Expand Down
21 changes: 7 additions & 14 deletions java/org/apache/catalina/startup/ExpandWar.java
Expand Up @@ -26,6 +26,7 @@
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
Expand Down Expand Up @@ -116,10 +117,7 @@ public static String expand(Host host, URL war, String pathname)
}

// Expand the WAR into the new document base directory
String canonicalDocBasePrefix = docBase.getCanonicalPath();
if (!canonicalDocBasePrefix.endsWith(File.separator)) {
canonicalDocBasePrefix += File.separator;
}
Path canonicalDocBasePath = docBase.getCanonicalFile().toPath();

// Creating war tracker parent (normally META-INF)
File warTrackerParent = warTracker.getParentFile();
Expand All @@ -134,14 +132,13 @@ public static String expand(Host host, URL war, String pathname)
JarEntry jarEntry = jarEntries.nextElement();
String name = jarEntry.getName();
File expandedFile = new File(docBase, name);
if (!expandedFile.getCanonicalPath().startsWith(
canonicalDocBasePrefix)) {
if (!expandedFile.getCanonicalFile().toPath().startsWith(canonicalDocBasePath)) {
// Trying to expand outside the docBase
// Throw an exception to stop the deployment
throw new IllegalArgumentException(
sm.getString("expandWar.illegalPath",war, name,
expandedFile.getCanonicalPath(),
canonicalDocBasePrefix));
canonicalDocBasePath));
}
int last = name.lastIndexOf('/');
if (last >= 0) {
Expand Down Expand Up @@ -217,10 +214,7 @@ public static void validate(Host host, URL war, String pathname) throws IOExcept
File docBase = new File(host.getAppBaseFile(), pathname);

// Calculate the document base directory
String canonicalDocBasePrefix = docBase.getCanonicalPath();
if (!canonicalDocBasePrefix.endsWith(File.separator)) {
canonicalDocBasePrefix += File.separator;
}
Path canonicalDocBasePath = docBase.getCanonicalFile().toPath();
JarURLConnection juc = (JarURLConnection) war.openConnection();
juc.setUseCaches(false);
try (JarFile jarFile = juc.getJarFile()) {
Expand All @@ -229,14 +223,13 @@ public static void validate(Host host, URL war, String pathname) throws IOExcept
JarEntry jarEntry = jarEntries.nextElement();
String name = jarEntry.getName();
File expandedFile = new File(docBase, name);
if (!expandedFile.getCanonicalPath().startsWith(
canonicalDocBasePrefix)) {
if (!expandedFile.getCanonicalFile().toPath().startsWith(canonicalDocBasePath)) {
// Entry located outside the docBase
// Throw an exception to stop the deployment
throw new IllegalArgumentException(
sm.getString("expandWar.illegalPath",war, name,
expandedFile.getCanonicalPath(),
canonicalDocBasePrefix));
canonicalDocBasePath));
}
}
} catch (IOException e) {
Expand Down
3 changes: 1 addition & 2 deletions java/org/apache/catalina/startup/HostConfig.java
Expand Up @@ -598,8 +598,7 @@ protected void deployDescriptor(ContextName cn, File contextXml) {
docBase = new File(host.getAppBaseFile(), context.getDocBase());
}
// If external docBase, register .xml as redeploy first
if (!docBase.getCanonicalPath().startsWith(
host.getAppBaseFile().getAbsolutePath() + File.separator)) {
if (!docBase.getCanonicalFile().toPath().startsWith(host.getAppBaseFile().toPath())) {
isExternal = true;
deployedApp.redeployResources.put(
contextXml.getAbsolutePath(),
Expand Down
4 changes: 4 additions & 0 deletions webapps/docs/changelog.xml
Expand Up @@ -225,6 +225,10 @@
<update>
Migrate to new code signing service. (markt)
</update>
<scode>
Use <code>java.nio.file.Path</code> to test for one directory being a
sub-directory of another in a consistent way. (markt)
</scode>
</changelog>
</subsection>
</section>
Expand Down

0 comments on commit 4785433

Please sign in to comment.