Perfect FileUtils

pull/146/head
johnniang 2019-04-19 08:31:05 +08:00
parent 8b688e784a
commit 3d17e0f786
2 changed files with 106 additions and 3 deletions

View File

@ -1,13 +1,17 @@
package run.halo.app.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
import run.halo.app.exception.ForbiddenException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Comparator;
import java.util.zip.ZipInputStream;
/**
* File utilities.
@ -15,6 +19,7 @@ import java.util.Comparator;
* @author johnniang
* @date 4/9/19
*/
@Slf4j
public class FileUtils {
private FileUtils() {
@ -62,4 +67,64 @@ public class FileUtils {
.map(Path::toFile)
.forEach(File::delete);
}
/**
* Checks directory traversal vulnerability.
*
* @param parentPath parent path must not be null.
* @param pathToCheck path to check must not be null
*/
public static void checkDirectoryTraversal(@NonNull String parentPath, @NonNull String pathToCheck) {
checkDirectoryTraversal(Paths.get(parentPath), Paths.get(pathToCheck));
}
/**
* Checks directory traversal vulnerability.
*
* @param parentPath parent path must not be null.
* @param pathToCheck path to check must not be null
*/
public static void checkDirectoryTraversal(@NonNull Path parentPath, @NonNull String pathToCheck) {
checkDirectoryTraversal(parentPath, Paths.get(pathToCheck));
}
/**
* Checks directory traversal vulnerability.
*
* @param parentPath parent path must not be null.
* @param pathToCheck path to check must not be null
*/
public static void checkDirectoryTraversal(@NonNull Path parentPath, @NonNull Path pathToCheck) {
Assert.notNull(parentPath, "Parent path must not be null");
Assert.notNull(pathToCheck, "Path to check must not be null");
if (pathToCheck.startsWith(parentPath.normalize())) {
return;
}
throw new ForbiddenException("You cannot access " + pathToCheck).setErrorData(pathToCheck);
}
public static void closeQuietly(InputStream inputStream) {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
// Ignore this exception
log.error("Failed to close input stream", e);
}
}
public static void closeQuietly(ZipInputStream zipInputStream) {
try {
if (zipInputStream != null) {
zipInputStream.closeEntry();
zipInputStream.close();
}
} catch (IOException e) {
// Ignore this exception
log.error("Failed to close zip input stream", e);
}
}
}

View File

@ -3,6 +3,7 @@ package run.halo.app.utils;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -17,10 +18,9 @@ public class DirectoryAttackTest {
private String userHome = System.getProperty("user.home");
@Test
public void compareDirectoryTest() {
public void compareDirectoryFailureTest() {
String workDir = userHome + "/halo-test/";
Path workDirPath = Paths.get(workDir);
Path workDirPath = Paths.get(userHome + "/halo-test/");
Path testPath = Paths.get(userHome + "/../../etc/passwd");
@ -30,4 +30,42 @@ public class DirectoryAttackTest {
Assert.assertFalse(testPath.startsWith(workDirPath));
Assert.assertFalse(workDirPath.startsWith(testPath));
}
@Test
public void compareDirectorySuccessfullyTest() {
Path workDirPath = Paths.get(userHome + "/halo-test/");
Path testPath = Paths.get(userHome + "/halo-test/test.txt");
System.out.println("Work directory path: " + workDirPath);
System.out.println("Test path: " + testPath);
Assert.assertTrue(testPath.startsWith(workDirPath));
Assert.assertFalse(workDirPath.startsWith(testPath));
}
@Test
public void compareDirectorySuccessfullyTest2() {
Path workDirPath = Paths.get(userHome + "/../../etc/").normalize();
Path testPath = Paths.get("/etc/passwd");
System.out.println("Work directory path: " + workDirPath);
System.out.println("Test path: " + testPath);
Assert.assertTrue(testPath.startsWith(workDirPath));
Assert.assertFalse(workDirPath.startsWith(testPath));
}
@Test
public void getRealPathTest() {
String pathname = "/home/test/../../etc/";
Path path = Paths.get(pathname);
System.out.println("Path: " + path);
System.out.println("Absolute path: " + path.toAbsolutePath());
System.out.println("Name count: " + path.getNameCount());
System.out.println("Normalized path: " + path.normalize());
}
}