Skip to content

Commit

Permalink
Prevent received files from escaping download dir
Browse files Browse the repository at this point in the history
  • Loading branch information
slowscript committed Dec 13, 2023
1 parent 11845b1 commit 24c86c5
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions app/src/main/java/slowscript/warpinator/Transfer.java
Original file line number Diff line number Diff line change
Expand Up @@ -549,9 +549,12 @@ private void createDirectory(String path) {
if (Server.current.downloadDirUri.startsWith("content:")) {
Uri rootUri = Uri.parse(Server.current.downloadDirUri);
DocumentFile root = DocumentFile.fromTreeUri(svc, rootUri);
createDirectories(root, path, null);
createDirectories(root, path, null); // Note: .. segment is created as (invalid)
} else {
if (!new File(Server.current.downloadDirUri, path).mkdirs()) {
File dir = new File(Server.current.downloadDirUri, path);
if (!validateFile(dir))
throw new IllegalArgumentException("The dir path leads outside download dir");
if (!dir.mkdirs()) {
errors.add("Failed to create directory " + path);
Log.e(TAG, "Failed to create directory " + path);
}
Expand Down Expand Up @@ -586,7 +589,7 @@ private OutputStream openFileStream(String fileName) throws FileNotFoundExceptio
if(Utils.pathExistsInTree(svc, rootUri, fileName)) {
fileName = handleUriExists(fileName);
}
//Get parent
//Get parent - createFile will substitute / with _ and checks if parent is descendant of tree root
DocumentFile parent = root;
if (fileName.contains("/")) {
String parentRelPath = fileName.substring(0, fileName.lastIndexOf("/"));
Expand All @@ -604,10 +607,22 @@ private OutputStream openFileStream(String fileName) throws FileNotFoundExceptio
if(currentFile.exists()) {
currentFile = handleFileExists(currentFile);
}
if (!validateFile(currentFile))
throw new IllegalArgumentException("The file name leads to a file outside download dir");
return new FileOutputStream(currentFile, false);
}
}

private boolean validateFile(File f) {
boolean res = false;
try {
res = (f.getCanonicalPath() + "/").startsWith(Server.current.downloadDirUri);
} catch (Exception e) {
Log.w(TAG, "Could not resolve canonical path for " + f.getAbsolutePath() + ": " + e.getMessage());
}
return res;
}

private String guessMimeType(String name) {
//We don't care about knowing the EXACT mime type
//This is only to prevent fail on some devices that reject empty mime type
Expand Down

0 comments on commit 24c86c5

Please sign in to comment.