Class FileSecurityValidator
java.lang.Object
tech.riemann.nif.starter.file.FileSecurityValidator
文件上传安全校验器
提供多维度的文件上传安全检查,所有维度交叉联动而非独立放行:
- 非空校验——拒绝零字节文件;
- 文件大小校验——读取真实字节数(而非仅
MultipartFile.getSize()声明值),并支持上限与下限; - 文件名安全性——空名/超长/XSS 攻击字符/路径穿越语义检测;
- 扩展名校验——黑名单优先、白名单次之;
- MIME 内容校验——基于 Apache Tika 对真实文件内容检测,与扩展名交叉比对;
- 扩展名-内容一致性——扩展名声明的类型与内容真实类型不符(伪装文件)直接拒绝;
- 落盘路径校验——
基于
invalid reference
#validateStoredPath(Path)getCanonicalPath()检测软链接与路径穿越。
与早期版本的关键差异:
早期版本在校验链中扩展名白名单命中即 return true,导致后续 MIME 内容检测被短路跳过,
攻击者可把 evil.exe 改名 evil.png 并塞入 PNG 头绕过内容检测。
本版本将扩展名与 MIME 改为双重必须都通过,并额外校验二者语义一致性。
失败处理:validate(MultipartFile) 在任一维度不通过时抛出
FileValidationException
(携带细分错误码,由全局异常处理器统一映射为 400);若调用方希望自行处理失败,可使用
validateDetailed(MultipartFile) 获取 FileValidationResult。
- Author:
- kerbores(kerbores@gmail.com)
-
Constructor Summary
ConstructorsConstructorDescriptionFileSecurityValidator(Set<String> allowedMimeTypes, long maxSize) 兼容构造(早期两参版本)FileSecurityValidator(Set<String> allowedMimeTypes, Set<String> allowedExtensions, Set<String> blockedExtensions, long maxSize, boolean checkFilenameXss, boolean checkPathTraversal, int maxFilenameLength) 兼容构造(早期七参版本) -
Method Summary
Modifier and TypeMethodDescriptionbooleanvalidate(org.springframework.web.multipart.MultipartFile file) 校验文件(失败抛异常)validateDetailed(org.springframework.web.multipart.MultipartFile file) 校验文件(返回结果对象,不抛异常)validateStoredPath(Path storedPath, Path allowedBaseDir) 校验已落盘文件的存储路径安全性
-
Constructor Details
-
FileSecurityValidator
-
FileSecurityValidator
-
-
Method Details
-
validate
校验文件(失败抛异常)- Parameters:
file- 上传的文件- Returns:
- 校验通过返回 true
- Throws:
FileValidationException- 任一维度不通过IOException- 读取文件流时发生异常
-
validateDetailed
public FileValidationResult validateDetailed(org.springframework.web.multipart.MultipartFile file) throws IOException 校验文件(返回结果对象,不抛异常)- Parameters:
file- 上传的文件- Returns:
- 校验结果
- Throws:
IOException- 读取文件流时发生异常
-
validateStoredPath
public FileValidationResult validateStoredPath(Path storedPath, Path allowedBaseDir) throws IOException 校验已落盘文件的存储路径安全性基于
Path.toRealPath(LinkOption...)/解析真实路径, 检测软链接逃逸与相对路径穿越——上传瞬间的文件名校验无法覆盖落盘后的真实路径, 业务层在完成文件写入后调用本方法对最终存储路径做最后一道防线。invalid reference
Files#getCanonicalPath- Parameters:
storedPath- 已落盘文件的真实路径allowedBaseDir- 允许存储的根目录(规范化后),若为空则不限制目录- Returns:
- 校验结果
- Throws:
IOException- 路径解析失败
-