mirror of https://github.com/halo-dev/halo
Perfect FileUtils
parent
8b688e784a
commit
3d17e0f786
|
@ -1,13 +1,17 @@
|
||||||
package run.halo.app.utils;
|
package run.halo.app.utils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import run.halo.app.exception.ForbiddenException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File utilities.
|
* File utilities.
|
||||||
|
@ -15,6 +19,7 @@ import java.util.Comparator;
|
||||||
* @author johnniang
|
* @author johnniang
|
||||||
* @date 4/9/19
|
* @date 4/9/19
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class FileUtils {
|
public class FileUtils {
|
||||||
|
|
||||||
private FileUtils() {
|
private FileUtils() {
|
||||||
|
@ -62,4 +67,64 @@ public class FileUtils {
|
||||||
.map(Path::toFile)
|
.map(Path::toFile)
|
||||||
.forEach(File::delete);
|
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package run.halo.app.utils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
@ -17,10 +18,9 @@ public class DirectoryAttackTest {
|
||||||
private String userHome = System.getProperty("user.home");
|
private String userHome = System.getProperty("user.home");
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void compareDirectoryTest() {
|
public void compareDirectoryFailureTest() {
|
||||||
|
|
||||||
String workDir = userHome + "/halo-test/";
|
Path workDirPath = Paths.get(userHome + "/halo-test/");
|
||||||
Path workDirPath = Paths.get(workDir);
|
|
||||||
|
|
||||||
Path testPath = Paths.get(userHome + "/../../etc/passwd");
|
Path testPath = Paths.get(userHome + "/../../etc/passwd");
|
||||||
|
|
||||||
|
@ -30,4 +30,42 @@ public class DirectoryAttackTest {
|
||||||
Assert.assertFalse(testPath.startsWith(workDirPath));
|
Assert.assertFalse(testPath.startsWith(workDirPath));
|
||||||
Assert.assertFalse(workDirPath.startsWith(testPath));
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue