Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion base/src/main/java/com/tinyengine/it/common/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,32 @@ private static File convertMultipartFileToFile(MultipartFile multipartFile) thro
private static List<FileInfo> processZipEntries(ZipInputStream zis, File tempDir) throws IOException {
List<FileInfo> fileInfoList = new ArrayList<>();
ZipEntry zipEntry;

// 将 tempDir 转为规范路径(例如解析符号链接、父目录等)
Comment thread
hexqi marked this conversation as resolved.
Path safeDir = tempDir.toPath().toRealPath();
log.info("Created temporary directory at: {}, real path: {}", tempDir.getAbsolutePath(), safeDir);
while ((zipEntry = zis.getNextEntry()) != null) {

// 获取 ZIP 条目中的路径(可能包含 ../ 或绝对路径)
String entryName = zipEntry.getName();

// 拼接并规范化路径
Path targetPath = safeDir.resolve(entryName).normalize();

log.info("Processing ZIP entry: {}, target path: {}", entryName, targetPath);

// 关键校验:确保目标路径仍在 safeDir 之下
if (!targetPath.startsWith(safeDir)) {
throw new SecurityException("检测到跨目录攻击: " + entryName);
}
File newFile = new File(tempDir, zipEntry.getName());
Comment thread
chilingling marked this conversation as resolved.
Outdated

if (zipEntry.isDirectory()) {
// 创建目录(同时确保父目录存在)
Files.createDirectories(targetPath);
fileInfoList.add(new FileInfo(newFile.getName(), "", true)); // 添加目录
} else {
// 确保父目录存在
Files.createDirectories(targetPath.getParent());
extractFile(zis, newFile); // 解压文件
fileInfoList.add(new FileInfo(newFile.getName(), readFileContent(newFile), false)); // 添加文件内容
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}
Expand Down
Loading