Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.datamate.datamanagement.domain.model.dataset.DatasetFile;
import com.datamate.datamanagement.domain.model.dataset.DatasetFileUploadCheckInfo;
import com.datamate.datamanagement.infrastructure.exception.DataManagementErrorCode;
import com.datamate.datamanagement.infrastructure.config.DataManagementProperties;
import com.datamate.datamanagement.infrastructure.persistence.repository.DatasetFileRepository;
import com.datamate.datamanagement.infrastructure.persistence.repository.DatasetRepository;
import com.datamate.datamanagement.interfaces.converter.DatasetConverter;
Expand Down Expand Up @@ -82,12 +83,16 @@ public class DatasetFileApplicationService {
@Value("${datamate.data-management.file.duplicate:COVER}")
private DuplicateMethod duplicateMethod;

private final DataManagementProperties dataManagementProperties;

@Autowired
public DatasetFileApplicationService(DatasetFileRepository datasetFileRepository,
DatasetRepository datasetRepository, FileService fileService) {
DatasetRepository datasetRepository, FileService fileService,
DataManagementProperties dataManagementProperties) {
this.datasetFileRepository = datasetFileRepository;
this.datasetRepository = datasetRepository;
this.fileService = fileService;
this.dataManagementProperties = dataManagementProperties;
}

/**
Expand Down Expand Up @@ -1114,6 +1119,13 @@ private void addFile(String sourPath, String targetPath, boolean softAdd) {
throw BusinessException.of(SystemErrorCode.FILE_SYSTEM_ERROR);
}

// 检查源路径是否在允许的目录范围内,防止任意文件读取
if (!isSourcePathAllowed(source)) {
log.warn("Source file path is outside allowed directories: {}", sourPath);
throw BusinessException.of(CommonErrorCode.PARAM_ERROR,
"Source file path is outside allowed directories: " + sourPath);
}

try {
if (Files.exists(target) && Files.isSameFile(source, target)) {
return;
Expand Down Expand Up @@ -1165,6 +1177,32 @@ private static DatasetFile getDatasetFileForAdd(AddFilesRequest req, AddFilesReq
.build();
}

/**
* 检查源文件路径是否在允许的目录范围内
*
* @param sourcePath 规范化后的源文件路径
* @return true 如果路径在任一允许目录内
*/
private boolean isSourcePathAllowed(Path sourcePath) {
List<String> allowedDirs = dataManagementProperties.getFileStorage().getAllowedSourceDirs();
if (allowedDirs == null || allowedDirs.isEmpty()) {
log.warn("No allowed source directories configured, denying source path: {}", sourcePath);
return false;
}

Path normalizedSource = sourcePath.normalize().toAbsolutePath();
for (String allowedDir : allowedDirs) {
if (StringUtils.isBlank(allowedDir)) {
continue;
}
Path normalizedAllowed = Paths.get(allowedDir).normalize().toAbsolutePath();
if (normalizedSource.startsWith(normalizedAllowed)) {
return true;
}
}
return false;
}

/**
* 安全地验证并获取文件路径,防止路径遍历攻击
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
* 数据管理服务配置属性
*/
Expand Down Expand Up @@ -33,6 +36,7 @@ public static class FileStorage {
private String uploadDir = "./uploads";
private long maxFileSize = 10485760; // 10MB
private long maxRequestSize = 52428800; // 50MB
private List<String> allowedSourceDirs = new ArrayList<>();

public String getUploadDir() {
return uploadDir;
Expand All @@ -57,6 +61,14 @@ public long getMaxRequestSize() {
public void setMaxRequestSize(long maxRequestSize) {
this.maxRequestSize = maxRequestSize;
}

public List<String> getAllowedSourceDirs() {
return allowedSourceDirs;
}

public void setAllowedSourceDirs(List<String> allowedSourceDirs) {
this.allowedSourceDirs = allowedSourceDirs;
}
}

public static class Cache {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ dataMate:
upload-dir: ${FILE_UPLOAD_DIR:./uploads}
max-file-size: 10485760 # 10MB
max-request-size: 52428800 # 50MB
allowed-source-dirs:
- ${DATASET_BASE_PATH:/dataset}
- ${FILE_UPLOAD_DIR:./uploads}
cache:
ttl: 3600
max-size: 1000
Expand Down
Loading