|
|
@@ -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("文件内容非法,不允许上传脚本或网页文件");
|
|
|
}
|