From 24f8d7b57127e2607ec05adb7c912b3decddeb99 Mon Sep 17 00:00:00 2001
From: guqing <38999863+guqing@users.noreply.github.com>
Date: Fri, 3 Jan 2025 17:32:13 +0800
Subject: [PATCH] fix: XSS vulnerability due to polyglot file type upload
(#7149)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
#### What type of PR is this?
/kind bug
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
修复文件类型限制能通过混合文件类型绕过检测的问题
参考:https://github.com/halo-dev/halo/security/advisories/GHSA-99mc-ch53-pqh9
#### Does this PR introduce a user-facing change?
```release-note
修复文件类型限制能通过混合文件类型绕过检测的问题
```
---
.../app/infra/utils/FileTypeDetectUtils.java | 38 +++++++++++++++++++
.../LocalAttachmentUploadHandler.java | 18 +++++++--
.../resources/config/i18n/messages.properties | 1 +
.../config/i18n/messages_zh.properties | 1 +
.../infra/utils/FileTypeDetectUtilsTest.java | 24 ++++++++++++
5 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/api/src/main/java/run/halo/app/infra/utils/FileTypeDetectUtils.java b/api/src/main/java/run/halo/app/infra/utils/FileTypeDetectUtils.java
index 7166260d4f..63663b0700 100644
--- a/api/src/main/java/run/halo/app/infra/utils/FileTypeDetectUtils.java
+++ b/api/src/main/java/run/halo/app/infra/utils/FileTypeDetectUtils.java
@@ -10,6 +10,7 @@
import org.apache.tika.metadata.TikaCoreProperties;
import org.apache.tika.mime.MimeTypeException;
import org.apache.tika.mime.MimeTypes;
+import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
@UtilityClass
@@ -54,4 +55,41 @@ public static String detectFileExtension(String mimeType) throws MimeTypeExcepti
MimeTypes mimeTypes = MimeTypes.getDefaultMimeTypes();
return mimeTypes.forName(mimeType).getExtension();
}
+
+ /**
+ *
Get file extension from file name.
+ *
The obtained file extension is in lowercase and includes the dot, such as ".jpg".
+ */
+ @NonNull
+ public static String getFileExtension(String fileName) {
+ Assert.notNull(fileName, "The fileName must not be null");
+ int lastDot = fileName.lastIndexOf(".");
+ if (lastDot > 0) {
+ return fileName.substring(lastDot).toLowerCase();
+ }
+ return "";
+ }
+
+ /**
+ *
Recommend to use this method to verify whether the file extension matches the file type
+ * after matching the file type to avoid XSS attacks such as bypassing detection by polyglot
+ * file