CVE-2023-40183: Unrestricted Upload of File with Dangerous Type (CWE-434)
value: DataEase is an open source data visualization and analysis tool. Prior to version 1.18.11, DataEase has a vulnerability that allows an attacker to to obtain user cookies. The program only uses the `ImageIO.read()` method to determine whether the file is an image file or not. There is no whitelisting restriction on file suffixes. This allows the attacker to synthesize the attack code into an image for uploading and change the file extension to html. The attacker may steal user cookies by accessing links. The vulnerability has been fixed in v1.18.11. There are no known workarounds.
CWE description: The product allows the upload or transfer of dangerous file types that are automatically processed within its environment.
CVSS v3 base score: 5.3
Published: 2023-09-21T15:15Z
Repository: https://github.com/dataease/dataease
Language: Other
Files changed: core/backend/src/main/java/io/dataease/service/staticResource/StaticResourceService.java, core/frontend/src/views/background/BackgroundOverall.vue, core/frontend/src/views/panel/appTemplate/AppTemplateContent.vue
Commit date: 2023-09-13 18:20:55 +0800
Commit message: fix: 加强图片校验，防止恶意代码通过合成到图片上传到服务器中引起的攻击行为

Diff: diff --git a/core/backend/src/main/java/io/dataease/service/staticResource/StaticResourceService.java b/core/backend/src/main/java/io/dataease/service/staticResource/StaticResourceService.java
index 19a8c5a04d..4353e96783 100644
--- a/core/backend/src/main/java/io/dataease/service/staticResource/StaticResourceService.java
+++ b/core/backend/src/main/java/io/dataease/service/staticResource/StaticResourceService.java
@@ -22,10 +22,12 @@ import java.io.InputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Author: wangjiahao
  * Date: 2022/4/24
  * Description:
@@ -63,13 +65,16 @@ public class StaticResourceService {
             image = ImageIO.read(input);
         } catch (IOException e) {
             LogUtil.error(e.getMessage(), e);
             return false;
         }
-        if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) {
+        Pattern pattern = Pattern.compile("\\.(png|jpg|jpeg|gif)$");
+        Matcher matcher = pattern.matcher(file.getOriginalFilename().toLowerCase());
+        if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0 || !matcher.find()) {
             return false;
         }
+
         return true;
     }
 
     public void saveFilesToServe(String staticResource) {
         Gson gson = new Gson();
diff --git a/core/frontend/src/views/background/BackgroundOverall.vue b/core/frontend/src/views/background/BackgroundOverall.vue
index a6bd5e5f85..cfc7e9cf94 100644
--- a/core/frontend/src/views/background/BackgroundOverall.vue
+++ b/core/frontend/src/views/background/BackgroundOverall.vue
@@ -108,11 +108,11 @@
             </el-radio>
           </el-col>
           <el-col style="width: 130px!important;">
             <el-upload
               action=""
-              accept=".jpeg,.jpg,.png,.gif,.svg"
+              accept=".jpeg,.jpg,.png,.gif"
               class="avatar-uploader"
               list-type="picture-card"
               :class="{disabled:uploadDisabled}"
               :on-preview="handlePictureCardPreview"
               :on-remove="handleRemove"
diff --git a/core/frontend/src/views/panel/appTemplate/AppTemplateContent.vue b/core/frontend/src/views/panel/appTemplate/AppTemplateContent.vue
index c0dcb90621..0dddb47a3a 100644
--- a/core/frontend/src/views/panel/appTemplate/AppTemplateContent.vue
+++ b/core/frontend/src/views/panel/appTemplate/AppTemplateContent.vue
@@ -84,11 +84,11 @@
           prop="icon"
         >
           <el-col style="width: 148px!important;height: 148px!important;overflow: hidden">
             <el-upload
               action=""
-              accept=".jpeg,.jpg,.png,.gif,.svg"
+              accept=".jpeg,.jpg,.png,.gif"
               class="avatar-uploader"
               list-type="picture-card"
               :class="{disabled:uploadDisabled}"
               :on-preview="handlePictureCardPreview"
               :on-remove="handleRemove"

Vulnerable code:         if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0) {
              accept=".jpeg,.jpg,.png,.gif,.svg"
              accept=".jpeg,.jpg,.png,.gif,.svg"
Fixed code: import java.util.regex.Matcher;
import java.util.regex.Pattern;
        Pattern pattern = Pattern.compile("\\.(png|jpg|jpeg|gif)$");
        Matcher matcher = pattern.matcher(file.getOriginalFilename().toLowerCase());
        if (image == null || image.getWidth() <= 0 || image.getHeight() <= 0 || !matcher.find()) {

              accept=".jpeg,.jpg,.png,.gif"
              accept=".jpeg,.jpg,.png,.gif"