当前位置: 首页 > news >正文

【PDF-XSS攻击】springboot项目-上传文件-解决PDF文件XSS攻击

  • 解决
    • pdfbox依赖
    • PdfUtils工具类

问题:

 1、pom.xml

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

2、PdfUtils.java

package com.hf.common.utils;import com.hf.common.core.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageTree;import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.stream.IntStream;@Slf4j
public class PdfUtils {/*** 校验pdf文件是否包含js脚本**/public static boolean containsJavaScript(File file) {PDDocument document = null;try {document = PDDocument.load(file);} catch (IOException e) {throw new BusinessException("检测pdf文件脚本失败");}return containsJavaScript(document);}/*** 通过流的方式校验pdf文件是否包含js脚本* 校验pdf文件是否包含js脚本**/public static boolean containsJavaScript(InputStream input) {PDDocument document = null;try {document = PDDocument.load(input);} catch (IOException e) {throw new BusinessException("检测pdf文件脚本失败");}return containsJavaScript(document);}/*** 文档的方式校验pdf文件是否包含js脚本*/private static boolean containsJavaScript(PDDocument document) {if (document.getDocument().getTrailer().toString().contains("COSName{JS}")|| document.getDocument().getTrailer().toString().contains("COSName{JavaScript}")) {return true;}PDPageTree pages = document.getPages();return IntStream.range(0, pages.getCount()).anyMatch(i -> {String pageContent = pages.get(i).getCOSObject().toString();return pageContent.contains("COSName{JS}") || pageContent.contains("COSName{JavaScript}");});}/*** 增强版PDF安全检查,检测空PDF和可能的恶意内容** @param file PDF文件* @return 是否安全*/public static boolean isSafePdf(File file) {PDDocument document = null;try {document = PDDocument.load(file);// 检查文件大小是否异常小
//            if (file.length() < 1024) { // 小于1KB的PDF文件可能有问题
//                log.error("PDF文件大小异常小: {} bytes", file.length());
//                return false;
//            }// 检查页面数量if (document.getNumberOfPages() == 0) {log.error("PDF文件没有页面");return false; // 空PDF文件}// 检查是否包含JavaScriptif (containsJavaScript(document)) {log.error("PDF文件包含JavaScript");return false;}// 检查文档结构中的可疑元素String trailerString = document.getDocument().getTrailer().toString().toLowerCase();if (trailerString.contains("/js") ||trailerString.contains("/javascript") ||trailerString.contains("/action") ||trailerString.contains("/launch") ||trailerString.contains("/submitform") ||trailerString.contains("/openaction")) {log.error("PDF文件包含可疑元素: {}", trailerString);return false;}return true;} catch (Exception e) {// 如果解析出错,认为文件不安全log.error("PDF文件解析失败", e);return false;} finally {if (document != null) {try {document.close();} catch (IOException e) {// 忽略关闭错误}}}}
}

 3、serviceimpl

 @Overridepublic ObjectFile upload(MultipartFile file, String user) throws Exception {if (file == null || file.isEmpty()) {throw new BusinessException("上传文件为空");}String fileName = file.getOriginalFilename();String contentTypes = file.getContentType();// 检查PDF文件安全性if (fileName != null && fileName.toLowerCase().endsWith(".pdf")) {File tempFile = File.createTempFile("upload_", ".pdf");try {FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(tempFile));// 使用增强的PDF安全检查if (!PdfUtils.isSafePdf(tempFile)) {throw new BusinessException("检测到不安全的PDF文件,上传失败");}} catch (IOException e) {throw new BusinessException("PDF文件安全检查失败: " + e.getMessage());} finally {tempFile.delete();}}
//上传minio服务器Map<String, String> map = minioService.uploadFile(file.getInputStream(), file.getSize(), fileName, contentTypes);if (MapUtil.isEmpty(map)) {throw new BusinessException("上传文件失败");}ObjectFile objectFile = new ObjectFile ();objectFile .setFileType(map.get("fileType"));objectFile .setNameOld(map.get("nameOld"));objectFile .setNameNew(map.get("nameNew"));objectFile .setPath(map.get("path"));objectFile .setInternalPath(map.get("internalPath"));if (StrUtil.isNotEmpty(user)) {objectFile .setCreateId(user);}iObjectFileService.save(objectFile );return objectFile ;}

使用python 生成的xss 空白文件

from PyPDF2 import PdfReader, PdfWriter
# 创建一个新的 PDF 文档
output_pdf = PdfWriter()
# 添加一个新页面
page = output_pdf.add_blank_page(width=72, height=72)
# 添加js代码
output_pdf.add_js("app.alert('xss');")
# 将新页面写入到新 PDF 文档中
with open("xss.pdf", "wb") as f:output_pdf.write(f)

文件2:生成带有内容的xss文件

from PyPDF2 import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from io import BytesIO# 第一步:用 reportlab 创建带有文本的 PDF 页面
packet = BytesIO()
can = canvas.Canvas(packet, pagesize=letter)
can.drawString(100, 750, "123")  # 添加你要写入的文本
can.save()
packet.seek(0)# 第二步:读取该页面并创建新的 PDF
new_pdf = PdfReader(packet)
output_pdf = PdfWriter()# 添加页面(带文字)
output_pdf.add_page(new_pdf.pages[0])# 添加 JavaScript(XSS 示例)
output_pdf.add_js("app.alert('xss');")# 第三步:写入最终 PDF 文件
with open("xss23.pdf", "wb") as f:output_pdf.write(f)

http://www.lqws.cn/news/594649.html

相关文章:

  • [密码学实战]深入解析ASN.1和DER编码:以数字签名值为例
  • 用openCV实现基础的人脸检测与情绪识别
  • 华为交换机堆叠与集群技术深度解析附带脚本
  • Sketch v2025「Athens」全新发布,3大更新重塑UI/UX设计的关键逻辑
  • stm32 单片机主要优点有哪些?
  • SAP ABAP 中 AMDP 简介及实现方法
  • Spring Boot 集成 Dufs 通过 WebDAV 实现文件管理
  • ES05 - 集群的运维和安全
  • 玄机——第一章应急响应-Linux日志分析
  • AILiquid线上AMA首秀,全链AI驱动的去中心化合约平台引发关注
  • 【项目笔记】高并发内存池项目剖析(二)
  • npm list的使用方法详细介绍
  • 【开源项目】一款真正可修改视频MD5工具视频质量不损失
  • uniapp+vue写小程序页面,实现一张图片默认放大后,可以在容器内上下左右拖动查看
  • 前端第二节(Vue)
  • 【实战】 容器中Spring boot项目 Graphics2D 画图中文乱码解决方案
  • anchor 智能合约案例3 之 journal
  • Docker进阶命令与参数——AI教你学Docker
  • 想做跑腿配送生意,怎么第三方平台订单对接?
  • MCU、LIN收发器、LIN总线、节点,它们之间是如何协作的?
  • SVN 分支管理(本文以Unity项目为例)
  • 以下是 Kafka 不同认证方式的配置示例,结合前面的单表设计方案,展示如何为每种认证方式填充配置表
  • 【Go-选项模式】
  • Spring Boot 2 多模块项目中配置文件的加载顺序
  • 2025年主流大厂Java后端面试题主题深度解析
  • 【深度学习新浪潮】人工智能在文物考古领域有哪些最新研究进展?
  • 基于开源AI大模型AI智能名片S2B2C商城小程序的流量转化与价值沉淀研究
  • 借助飞算AI新手小白快速入门Java实操记录
  • AbMole| H₂DCFDA(M9096;活性氧(ROS)探针)
  • C#基础(DllImport)