mirror of
https://github.com/dataease/dataease.git
synced 2026-06-12 16:31:11 +08:00
fix: 【漏洞】修复HttpClientUtil.java的漏洞
This commit is contained in:
@@ -5,6 +5,7 @@ import lombok.Data;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
@@ -38,6 +39,9 @@ import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -395,14 +399,14 @@ public class HttpClientUtil {
|
||||
}
|
||||
throw new Exception(msg);
|
||||
}
|
||||
String fileName = extractFileName(response, url);
|
||||
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
String fileName = normalizeDownloadFileName(extractFileName(response, url));
|
||||
String suffix = extractSuffix(fileName);
|
||||
String tranName = UUID.randomUUID().toString() + "." + suffix;
|
||||
name.put("fileName", fileName);
|
||||
name.put("tranName", tranName);
|
||||
File localFile = new File(path + tranName);
|
||||
Path localFile = resolveDownloadPath(path, tranName);
|
||||
try (InputStream is = response.getEntity().getContent();
|
||||
FileOutputStream outputStream = new FileOutputStream(localFile)) {
|
||||
OutputStream outputStream = Files.newOutputStream(localFile)) {
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = is.read(buffer)) != -1) {
|
||||
@@ -417,15 +421,26 @@ public class HttpClientUtil {
|
||||
}
|
||||
|
||||
private static String extractFileName(HttpResponse response, String url) {
|
||||
url = URLDecoder.decode(url);
|
||||
String fileName = "";
|
||||
String disposition = response.getHeaders("Content-Disposition").toString();
|
||||
if (disposition != null) {
|
||||
int filenameIndex = disposition.indexOf("filename=");
|
||||
if (filenameIndex > 0) {
|
||||
fileName = disposition.substring(filenameIndex + 9)
|
||||
.replaceAll("\"", "") // 去除引号
|
||||
.trim();
|
||||
url = URLDecoder.decode(url, StandardCharsets.UTF_8);
|
||||
String fileName = StringUtils.EMPTY;
|
||||
Header dispositionHeader = response.getFirstHeader("Content-Disposition");
|
||||
if (dispositionHeader != null && StringUtils.isNotBlank(dispositionHeader.getValue())) {
|
||||
String disposition = dispositionHeader.getValue();
|
||||
int filenameStarIndex = disposition.indexOf("filename*=");
|
||||
if (filenameStarIndex >= 0) {
|
||||
fileName = disposition.substring(filenameStarIndex + 10).trim();
|
||||
int charsetIndex = fileName.indexOf("''");
|
||||
if (charsetIndex >= 0) {
|
||||
fileName = fileName.substring(charsetIndex + 2);
|
||||
}
|
||||
fileName = URLDecoder.decode(fileName.replace("\"", "").trim(), StandardCharsets.UTF_8);
|
||||
} else {
|
||||
int filenameIndex = disposition.indexOf("filename=");
|
||||
if (filenameIndex >= 0) {
|
||||
fileName = disposition.substring(filenameIndex + 9)
|
||||
.replace("\"", "")
|
||||
.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fileName.isEmpty()) {
|
||||
@@ -434,12 +449,43 @@ public class HttpClientUtil {
|
||||
? url.substring(url.lastIndexOf('/') + 1)
|
||||
: "download_" + System.currentTimeMillis();
|
||||
}
|
||||
if (fileName.trim().isEmpty()) {
|
||||
fileName = "download_" + System.currentTimeMillis();
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
private static String normalizeDownloadFileName(String fileName) {
|
||||
String normalizedFileName = StringUtils.trimToEmpty(fileName);
|
||||
if (normalizedFileName.isEmpty()) {
|
||||
normalizedFileName = "download_" + System.currentTimeMillis();
|
||||
}
|
||||
int separatorIndex = Math.max(normalizedFileName.lastIndexOf('/'), normalizedFileName.lastIndexOf('\\'));
|
||||
if (separatorIndex >= 0) {
|
||||
normalizedFileName = normalizedFileName.substring(separatorIndex + 1);
|
||||
}
|
||||
if (normalizedFileName.isEmpty()) {
|
||||
normalizedFileName = "download_" + System.currentTimeMillis();
|
||||
}
|
||||
FileUtils.validateUploadFilename(normalizedFileName);
|
||||
return normalizedFileName;
|
||||
}
|
||||
|
||||
private static String extractSuffix(String fileName) {
|
||||
int suffixIndex = fileName.lastIndexOf(".");
|
||||
if (suffixIndex < 0 || suffixIndex == fileName.length() - 1) {
|
||||
return "bin";
|
||||
}
|
||||
return fileName.substring(suffixIndex + 1);
|
||||
}
|
||||
|
||||
private static Path resolveDownloadPath(String path, String fileName) {
|
||||
FileUtils.validateUploadFilename(fileName);
|
||||
Path directory = Paths.get(path).toAbsolutePath().normalize();
|
||||
Path target = directory.resolve(fileName).normalize();
|
||||
if (!target.startsWith(directory)) {
|
||||
DEException.throwException("invalid download path");
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
public static byte[] downloadBytes(String url) {
|
||||
HttpClientConfig config = new HttpClientConfig();
|
||||
return HttpClientUtil.downFromRemote(url, config);
|
||||
|
||||
Reference in New Issue
Block a user