xw пре 6 дана
родитељ
комит
8233fed350

+ 8 - 4
fs-admin/src/main/java/com/fs/web/controller/common/CommonController.java

@@ -30,6 +30,7 @@ import com.fs.common.annotation.RateLimiter;
 import com.fs.common.enums.LimitType;
 import com.fs.common.constant.Constants;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.file.FileUploadUtils;
 import com.fs.common.utils.file.FileUtils;
@@ -173,6 +174,7 @@ public class CommonController
     @PostMapping("common/uploadOSS")
     public R uploadOSS(@RequestParam("file") MultipartFile file) throws Exception
     {
+        SecurityUtils.getUserId();
         String suffix = OssUploadUtils.validateAndGetSuffix(file);
         CloudStorageService storage = OSSFactory.build();
         String url = storage.uploadSuffix(file.getBytes(), suffix);
@@ -182,15 +184,16 @@ public class CommonController
     @PostMapping("/common/uploadWang")
     public WangUploadVO uploadWang(@RequestParam(value = "fileName", required = false) MultipartFile file) throws Exception
     {
-        WangUploadVO vo=new WangUploadVO();
+        WangUploadVO vo = new WangUploadVO();
         try
         {
-            String suffix = OssUploadUtils.validateAndGetSuffix(file);
+            SecurityUtils.getUserId();
+            String suffix = OssUploadUtils.validateWangEditorImageAndGetSuffix(file);
             CloudStorageService storage = OSSFactory.build();
             String url = storage.uploadSuffix(file.getBytes(), suffix);
             vo.setErrno(0);
-            List<WangUploadVO.WangUploadItem> items=new ArrayList<>();
-            WangUploadVO.WangUploadItem item=new WangUploadVO.WangUploadItem();
+            List<WangUploadVO.WangUploadItem> items = new ArrayList<>();
+            WangUploadVO.WangUploadItem item = new WangUploadVO.WangUploadItem();
             item.setUrl(url);
             items.add(item);
             vo.setData(items);
@@ -198,6 +201,7 @@ public class CommonController
         }
         catch (Exception e)
         {
+            log.warn(" 图片上传失败: {}", e.getMessage());
             vo.setErrno(-1);
             return vo;
         }

+ 49 - 4
fs-common/src/main/java/com/fs/common/utils/file/OssUploadUtils.java

@@ -13,6 +13,9 @@ public class OssUploadUtils
     /** OSS 单文件最大 10MB */
     public static final long OSS_MAX_SIZE = 10L * 1024 * 1024;
 
+    /** WangEditor 富文本图片上传单文件最大 5MB */
+    public static final long WANG_EDITOR_MAX_SIZE = 5L * 1024 * 1024;
+
     /** OSS 允许上传的文件后缀白名单(不含 html/js 等可执行类型) */
     public static final String[] OSS_ALLOWED_EXTENSION = {
             "bmp", "gif", "jpg", "jpeg", "png",
@@ -22,6 +25,12 @@ public class OssUploadUtils
             "mp3", "wav"
     };
 
+    /** 禁止上传的危险后缀 */
+    private static final String[] DANGEROUS_EXTENSIONS = {
+            "js", "jsx", "html", "htm", "svg", "php", "jsp", "asp", "aspx",
+            "exe", "sh", "bat", "cmd", "vbs", "ps1", "war", "jar"
+    };
+
     private OssUploadUtils()
     {
     }
@@ -30,6 +39,19 @@ public class OssUploadUtils
      * 校验上传文件并返回经文件头验证后的后缀(带点,如 ".jpg")
      */
     public static String validateAndGetSuffix(MultipartFile file)
+    {
+        return doValidateAndGetSuffix(file, OSS_ALLOWED_EXTENSION, OSS_MAX_SIZE);
+    }
+
+    /**
+     * WangEditor 富文本编辑器图片上传校验(仅允许图片类型)
+     */
+    public static String validateWangEditorImageAndGetSuffix(MultipartFile file)
+    {
+        return doValidateAndGetSuffix(file, MimeTypeUtils.IMAGE_EXTENSION, WANG_EDITOR_MAX_SIZE);
+    }
+
+    private static String doValidateAndGetSuffix(MultipartFile file, String[] allowedExtension, long maxSize)
     {
         if (file == null || file.isEmpty())
         {
@@ -41,19 +63,24 @@ public class OssUploadUtils
         {
             throw new OssException("文件名不能为空");
         }
+        assertSafeFileName(fileName);
         if (fileName.length() > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
         {
             throw new OssException("文件名长度超出限制");
         }
 
         long size = file.getSize();
-        if (size > OSS_MAX_SIZE)
+        if (size > maxSize)
         {
-            throw new OssException("文件大小超出限制,最大允许 " + (OSS_MAX_SIZE / 1024 / 1024) + "MB");
+            throw new OssException("文件大小超出限制,最大允许 " + (maxSize / 1024 / 1024) + "MB");
         }
 
         String extension = FileUploadUtils.getExtension(file);
-        if (!FileUploadUtils.isAllowedExtension(extension, OSS_ALLOWED_EXTENSION))
+        if (StringUtils.isEmpty(extension))
+        {
+            throw new OssException("无法识别文件类型");
+        }
+        if (!FileUploadUtils.isAllowedExtension(extension, allowedExtension))
         {
             throw new OssException("文件类型不允许上传");
         }
@@ -74,6 +101,22 @@ public class OssUploadUtils
         return "." + extension.toLowerCase();
     }
 
+    private static void assertSafeFileName(String fileName)
+    {
+        if (fileName.contains("..") || fileName.contains("/") || fileName.contains("\\") || fileName.contains("\0"))
+        {
+            throw new OssException("文件名非法");
+        }
+        String lower = fileName.toLowerCase();
+        for (String dangerous : DANGEROUS_EXTENSIONS)
+        {
+            if (lower.endsWith("." + dangerous) || lower.contains("." + dangerous + "."))
+            {
+                throw new OssException("文件类型不允许上传");
+            }
+        }
+    }
+
     private static void assertNotDangerousContent(byte[] bytes, String fileName)
     {
         if (bytes.length == 0)
@@ -85,7 +128,9 @@ public class OssUploadUtils
         String head = new String(bytes, 0, checkLen, StandardCharsets.UTF_8).trim().toLowerCase();
         if (head.startsWith("<!doctype html") || head.startsWith("<html")
                 || head.startsWith("<script") || head.startsWith("<?php")
-                || head.contains("<script") || head.contains("javascript:"))
+                || head.contains("<script") || head.contains("javascript:")
+                || head.contains("function ") || head.contains("eval(")
+                || head.startsWith("var ") || head.startsWith("const "))
         {
             throw new OssException("文件内容非法,不允许上传脚本或网页文件");
         }

+ 12 - 4
fs-company/src/main/java/com/fs/company/controller/common/CommonController.java

@@ -1,6 +1,8 @@
 package com.fs.company.controller.common;
 
 import cn.hutool.json.JSONUtil;
+import com.fs.common.annotation.RateLimiter;
+import com.fs.common.enums.LimitType;
 import com.fs.common.config.FSConfig;
 import com.fs.common.constant.Constants;
 import com.fs.common.core.domain.AjaxResult;
@@ -17,6 +19,7 @@ import com.fs.company.utils.AudioUtils;
 import com.fs.company.vo.WangUploadVO;
 import com.fs.course.service.ITencentCloudCosService;
 import com.fs.framework.config.ServerConfig;
+import com.fs.framework.security.SecurityUtils;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.service.TokenService;
 import com.fs.his.domain.FsExportTask;
@@ -222,9 +225,11 @@ public class CommonController
         }
     }
 
+    @RateLimiter(time = 60, count = 30, limitType = LimitType.IP, msg = "上传过于频繁,请稍后再试")
     @PostMapping("common/uploadOSS")
     public R uploadOSS(@RequestParam("file") MultipartFile file) throws Exception
     {
+        SecurityUtils.getLoginUser();
         String suffix = OssUploadUtils.validateAndGetSuffix(file);
         CloudStorageService storage = OSSFactory.build();
         String url = storage.uploadSuffix(file.getBytes(), suffix);
@@ -284,18 +289,20 @@ public class CommonController
 
         return R.ok().put("mp3Url", mp3Url).put("silkUrl", silkUrl);
     }
+    @RateLimiter(time = 60, count = 30, limitType = LimitType.IP, msg = "上传过于频繁,请稍后再试")
     @PostMapping("/common/uploadWang")
     public WangUploadVO uploadWang(@RequestParam(value = "fileName", required = false) MultipartFile file) throws Exception
     {
-        WangUploadVO vo=new WangUploadVO();
+        WangUploadVO vo = new WangUploadVO();
         try
         {
-            String suffix = OssUploadUtils.validateAndGetSuffix(file);
+            SecurityUtils.getLoginUser();
+            String suffix = OssUploadUtils.validateWangEditorImageAndGetSuffix(file);
             CloudStorageService storage = OSSFactory.build();
             String url = storage.uploadSuffix(file.getBytes(), suffix);
             vo.setErrno(0);
-            List<WangUploadVO.WangUploadItem> items=new ArrayList<>();
-            WangUploadVO.WangUploadItem item=new WangUploadVO.WangUploadItem();
+            List<WangUploadVO.WangUploadItem> items = new ArrayList<>();
+            WangUploadVO.WangUploadItem item = new WangUploadVO.WangUploadItem();
             item.setUrl(url);
             items.add(item);
             vo.setData(items);
@@ -303,6 +310,7 @@ public class CommonController
         }
         catch (Exception e)
         {
+            log.warn(" 图片上传失败: {}", e.getMessage());
             vo.setErrno(-1);
             return vo;
         }

+ 8 - 13
fs-service/src/main/java/com/fs/course/service/impl/HuaweiObsServiceImpl.java

@@ -157,29 +157,24 @@ public class HuaweiObsServiceImpl implements IHuaweiObsService {
 
 
     public static String generateUploadFileName(String fileName) {
-        // 获取文件扩展名
         String fileExtension = "";
         int i = fileName.lastIndexOf('.');
-        if (i > 0) {
-            fileExtension = fileName.substring(i + 1);
+        if (i > 0 && i < fileName.length() - 1) {
+            fileExtension = fileName.substring(i + 1).toLowerCase();
+        }
+        if (!fileExtension.matches("[a-z0-9]{1,10}")) {
+            fileExtension = "bin";
         }
 
-        // 获取当前时间戳
-        long currentTimeMillis = System.currentTimeMillis();
-
-        // 生成上传文件名
-        String uploadFileName = currentTimeMillis + "." + fileExtension;
+        String uuid = UUID.randomUUID().toString().replace("-", "");
+        String uploadFileName = uuid + "." + fileExtension;
 
-        // 获取当前日期
         Date date = new Date();
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
         dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
         String uploadDay = dateFormat.format(date);
 
-        // 生成上传路径
-        String key = "fs/" + uploadDay + "/" + uploadFileName;
-
-        return key;
+        return "fs/" + uploadDay + "/" + uploadFileName;
     }
 
     @Autowired

+ 14 - 6
fs-store/src/main/java/com/fs/store/controller/common/CommonController.java

@@ -1,11 +1,14 @@
 package com.fs.store.controller.common;
 
 import com.fs.store.vo.WangUploadVO;
+import com.fs.common.annotation.RateLimiter;
+import com.fs.common.enums.LimitType;
 import com.fs.common.config.FSConfig;
 import com.fs.common.constant.Constants;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.exception.file.OssException;
+import com.fs.common.utils.SecurityUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.file.FileUploadUtils;
 import com.fs.common.utils.file.FileUtils;
@@ -30,7 +33,7 @@ import java.util.List;
 
 /**
  * 通用请求处理
- * 
+ *
 
  */
 @RestController
@@ -45,7 +48,7 @@ public class CommonController
 
     /**
      * 通用下载请求
-     * 
+     *
      * @param fileName 文件名称
      * @param delete 是否删除
      */
@@ -126,26 +129,30 @@ public class CommonController
         }
     }
 
+    @RateLimiter(time = 60, count = 30, limitType = LimitType.IP, msg = "上传过于频繁,请稍后再试")
     @PostMapping("common/uploadOSS")
     public R uploadOSS(@RequestParam("file") MultipartFile file) throws Exception
     {
+        SecurityUtils.getUserId();
         String suffix = OssUploadUtils.validateAndGetSuffix(file);
         CloudStorageService storage = OSSFactory.build();
         String url = storage.uploadSuffix(file.getBytes(), suffix);
         return R.ok().put("url", url);
     }
+    @RateLimiter(time = 60, count = 30, limitType = LimitType.IP, msg = "上传过于频繁,请稍后再试")
     @PostMapping("/common/uploadWang")
     public WangUploadVO uploadWang(@RequestParam(value = "fileName", required = false) MultipartFile file) throws Exception
     {
-        WangUploadVO vo=new WangUploadVO();
+        WangUploadVO vo = new WangUploadVO();
         try
         {
-            String suffix = OssUploadUtils.validateAndGetSuffix(file);
+            SecurityUtils.getUserId();
+            String suffix = OssUploadUtils.validateWangEditorImageAndGetSuffix(file);
             CloudStorageService storage = OSSFactory.build();
             String url = storage.uploadSuffix(file.getBytes(), suffix);
             vo.setErrno(0);
-            List<WangUploadVO.WangUploadItem> items=new ArrayList<>();
-            WangUploadVO.WangUploadItem item=new WangUploadVO.WangUploadItem();
+            List<WangUploadVO.WangUploadItem> items = new ArrayList<>();
+            WangUploadVO.WangUploadItem item = new WangUploadVO.WangUploadItem();
             item.setUrl(url);
             items.add(item);
             vo.setData(items);
@@ -153,6 +160,7 @@ public class CommonController
         }
         catch (Exception e)
         {
+            log.warn(" 图片上传失败: {}", e.getMessage());
             vo.setErrno(-1);
             return vo;
         }