You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用开源Java工具(如PDFBox)清理PDF?Spring应用文件上传安全处理

增强Spring文件上传模块安全性的方案

一、前置基础校验

先做最核心的拦截,避免恶意文件进入后续处理流程:

  • 扩展名+文件头双重校验:
    不要仅依赖文件名后缀,读取文件前几个字节判断真实类型(即魔术字节):
    • PDF:%PDF-
    • DOCX:PK\x03\x04
    • XLS:D0CF11E0
    • JPG:FFD8FF
      实现时可写工具类,读取输入流前N字节做匹配,不匹配直接拒绝上传。
  • 严格限制文件大小:
    在Spring配置中设置spring.servlet.multipart.max-file-size和spring.servlet.multipart.max-request-size,或在代码中通过MultipartFile.getSize()直接判断,超出阈值直接拦截。

二、针对不同文件类型的内容清理

1. PDF文件清理(基于PDFBox)

PDF的危险点主要是JavaScript、自动执行动作、嵌入式文件、恶意注解,用PDFBox可直接移除这些内容:

依赖引入(Maven)

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.32</version>
</dependency>

清理核心代码

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.interactive.action.PDAction;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class PdfCleaner {
    public static void cleanPdf(InputStream inputStream, OutputStream outputStream) throws IOException {
        try (PDDocument document = PDDocument.load(inputStream)) {
            // 移除文档级自动执行动作(如打开时运行脚本)
            document.getDocumentCatalog().setOpenAction(null);
            
            // 遍历所有页面,清理页面动作与注解中的恶意内容
            for (PDPage page : document.getPages()) {
                page.setActions(null); // 清空页面关联的所有动作
                
                if (page.getAnnotations() != null) {
                    for (PDAnnotation annotation : page.getAnnotations()) {
                        // 移除链接注解中的JavaScript动作
                        if (annotation instanceof PDAnnotationLink) {
                            PDAnnotationLink link = (PDAnnotationLink) annotation;
                            PDAction action = link.getAction();
                            if (action instanceof PDActionJavaScript) {
                                link.setAction(null);
                            }
                        }
                        annotation.setActions(null); // 清空注解自带的动作
                    }
                }
            }
            
            // 移除嵌入式文件(防止隐藏恶意程序)
            if (document.getDocumentCatalog().getNames() != null) {
                document.getDocumentCatalog().getNames().setEmbeddedFiles(null);
            }
            
            // 保存清理后的文档
            document.save(outputStream);
        }
    }
}

2. Office文档(XLS、DOCX)清理

Office文档的风险点是宏、嵌入式对象、恶意公式,用Apache POI处理:

  • DOCX:使用XWPFDocument遍历段落和表格,提取纯文本后重新生成无宏的干净文档,或直接删除宏相关的XML部件;
  • XLS:使用HSSFWorkbook/XSSFWorkbook移除宏模块、嵌入式对象,禁用自动计算公式(通过设置setForceFormulaRecalculation(false))。

3. 图片文件处理

图片可能携带恶意元数据(如EXIF中的脚本)或隐写内容,通过重新编码清除:

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.OutputStream;

public class ImageCleaner {
    public static void cleanImage(InputStream inputStream, OutputStream outputStream, String format) throws IOException {
        BufferedImage image = ImageIO.read(inputStream);
        // 重新编码后会丢失所有元数据,仅保留图像本身
        ImageIO.write(image, format, outputStream);
    }
}

三、上传全流程安全管控

  • 文件存储规则:上传后用UUID生成随机文件名,避免路径遍历攻击;存储目录不要放在Web根目录下,禁止直接通过URL访问;
  • 二次扫描:除上传前的杀毒检测,可定时对已存储文件进行病毒扫描,弥补单次扫描的遗漏;
  • 权限控制:仅允许授权用户上传,下载文件时校验用户权限,防止未授权访问;
  • 目录权限设置:存储文件的目录设置为不可执行,即使文件被篡改也无法在服务器上运行。

内容的提问来源于stack exchange,提问作者Faisul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:40:25