java-springboot文件上传校验之只允许上传excel文件,且检查不能是脚本或者有害文件或可行性文件

  1. 四重验证机制

    • 文件扩展名检查(.xlsx/.xls)
    • MIME类型检查
    • 文件魔数验证(真实文件类型)
    • 可执行文件特征检测
  2. 防御措施

    • 使用try-with-resources确保流关闭
    • 限制文件大小防止DoS攻击
    • 使用Apache POI的FileMagic进行专业验证
  3. 生产环境建议

    Yaml

    # application.yml配置 spring: servlet: multipart: max-file-size: 10MB max-request-size: 10MB

完整代码:

java 复制代码
import org.apache.poi.poifs.filesystem.FileMagic;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

// 文件上传限制-只允许上传excel文件,且检查不能是脚本或者有害文件或可行性文件
public class ExcelFileValidator {

    // 允许的Excel文件MIME类型
    private static final String[] ALLOWED_MIME_TYPES = {
            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // .xlsx
            "application/vnd.ms-excel" // .xls
    };

    // 最大文件大小(10MB)
    private static final long MAX_FILE_SIZE = 10 * 1024 * 1024;

    /**
     * 验证Excel文件安全性
     *
     * @param file 上传的文件
     * @throws IOException              文件读取异常
     * @throws IllegalArgumentException 文件非法时抛出
     */
    public static void validateExcelFile(MultipartFile file) throws IOException, IllegalArgumentException {
        // 基础检查
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("请选择要上传的文件");
        }

        // 检查文件大小
        if (file.getSize() > MAX_FILE_SIZE) {
            throw new IllegalArgumentException("Excel文件大小不能超过10MB");
        }

        // 检查文件扩展名
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null ||
                (!originalFilename.toLowerCase().endsWith(".xlsx") &&
                        !originalFilename.toLowerCase().endsWith(".xls"))) {
            throw new IllegalArgumentException("仅支持.xlsx或.xls格式的Excel文件");
        }

        // 检查MIME类型
        String contentType = file.getContentType();
        if (contentType == null || !Arrays.asList(ALLOWED_MIME_TYPES).contains(contentType.toLowerCase())) {
            throw new IllegalArgumentException("非法的Excel文件类型");
        }

        // 使用POI检查文件魔数(真实文件类型)
        try (InputStream inputStream = file.getInputStream()) {
            FileMagic fileMagic = FileMagic.valueOf(inputStream);
            if (fileMagic != FileMagic.OLE2 && fileMagic != FileMagic.OOXML) {
                throw new IllegalArgumentException("非法的Excel文件格式");
            }

            // 基础恶意内容检查
            checkForExecutableContent(inputStream);
        }
    }

    /**
     * 检查是否包含可执行文件特征
     */
    private static void checkForExecutableContent(InputStream is) throws IOException {
        byte[] buffer = new byte[1024];
        is.read(buffer);

        // PE文件头检查(Windows可执行文件)
        if (buffer.length > 60 && buffer[0] == 0x4D && buffer[1] == 0x5A) {
            throw new IllegalArgumentException("检测到潜在有害文件内容");
        }

        // ELF文件头检查(Linux可执行文件)
        if (buffer.length > 4 && buffer[0] == 0x7F && buffer[1] == 0x45 &&
                buffer[2] == 0x4C && buffer[3] == 0x46) {
            throw new IllegalArgumentException("检测到潜在有害文件内容");
        }
    }
}
相关推荐
无心水1 小时前
【分布式利器:腾讯TSF】10、TSF故障排查与架构评审实战:Java架构师从救火到防火的生产哲学
java·人工智能·分布式·架构·限流·分布式利器·腾讯tsf
一 乐8 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
Boilermaker19928 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
Cherry的跨界思维8 小时前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
それども8 小时前
Apache POI XSSFWorkbook 和 SXSSFWorkbook 的区别
apache·excel
alonewolf_999 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
一嘴一个橘子9 小时前
spring-aop 的 基础使用(啥是增强类、切点、切面)- 2
java
sheji34169 小时前
【开题答辩全过程】以 中医药文化科普系统为例,包含答辩的问题和答案
java
恋爱绝缘体19 小时前
2020重学C++重构你的C++知识体系
java·开发语言·c++·算法·junit
wszy180910 小时前
新文章标签:让用户一眼发现最新内容
java·python·harmonyos