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

文章目录

  • 背景
  • 解决
    • pdfbox依赖
    • 控制器代码
    • PdfUtils工具类
  • 验证
  • 最后
    • 源码参考

背景

在这里插入图片描述

  • 上传xss-pdf造成存储型xss
  • 因为在浏览器直接预览的PDF,而不是预览,所以安全部门认为会有XSS漏洞
    在这里插入图片描述
    在这里插入图片描述

解决

  • 安全部门修复建议

1、根据白名单的标签和属性对数据进行过滤,以此来对可执行的脚本进行清除(如script标签,img标签的onerror属性等)。
2、对输入的数据进行HTML转义,使其不会识别为可执行脚本。

pdfbox依赖

<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox --><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.31</version></dependency>

控制器代码

@PostMapping("upload")public Object upload(MultipartFile file, HttpServletRequest request) throws IOException {// 文件后缀String fileName = file.getOriginalFilename();String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();// 判断是否是pdf文件类型if (StrUtil.equals(suffix, "pdf")) {// 判断文件xss攻击boolean haveJavaScript = PdfUtils.containsJavaScript(PdfUtils.multipartFileToFile(file));if (haveJavaScript) {return ("对不起,您上传的文件[" + fileName + "]包含xss脚本代码!");}}return "上传成功";}

PdfUtils工具类

/*** 获取不带扩展名的文件名*/public static String getFileNameNoSuffix(String filename) {if ((filename != null) && (filename.length() > 0)) {int dot = filename.lastIndexOf('.');if ((dot > -1) && (dot < (filename.length()))) {return filename.substring(0, dot);}}return filename;}/*** 获取文件扩展名*/public static String getSuffixNameName(String filename) {if ((filename != null) && (filename.length() > 0)) {int dot = filename.lastIndexOf('.');if ((dot > -1) && (dot < (filename.length() - 1))) {return filename.substring(dot + 1);}}return filename;}/*** File转MultipartFile** @param mulFile 文件对象* @return Multipart文件对象*/public static File multipartFileToFile(MultipartFile mulFile) throws IOException {InputStream ins = mulFile.getInputStream();String fileName = mulFile.getOriginalFilename();String prefix = getFileNameNoSuffix(fileName) + UUID.randomUUID().toString();String suffix = "." + getSuffixNameName(fileName);File toFile = File.createTempFile(prefix, suffix);OutputStream os = new FileOutputStream(toFile);int bytesRead = 0;byte[] buffer = new byte[8192];while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {os.write(buffer, 0, bytesRead);}os.close();ins.close();return toFile;}/*** 校验pdf文件是否包含js脚本**/public static boolean containsJavaScript(File file) throws IOException {RandomAccessFile is = new RandomAccessFile(file, "r");try {PDFParser parser = new PDFParser(is);parser.parse();PDDocument doc = parser.getPDDocument();String CosName = doc.getDocument().getTrailer().toString();if (CosName.contains("COSName{JavaScript}") || CosName.contains("COSName{JS}")) {return true;}} catch (Exception e) {log.error("PDF效验异常:" + e.getMessage());return true;} finally {is.close();}return false;}

验证

  • 上传一个带有XSS的PDF, 可以在资源绑定下载实例pdf或者连接下载
  • https://download.csdn.net/download/u010800804/89095359
    在这里插入图片描述
  • 其他没有XSS的PDF正常上传
    在这里插入图片描述

最后

源码参考

  • https://gitcode.com/rundreamsFly/java-upload-file-pdf-xss/tree/main

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/805504.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA之MDC的使用教程

文章目录 MDC简介MDC原理作用整体流程添加MDC依赖配置MDC 基本使用过程 MDC简介 MDC(Mapped Diagnostic Context)是用于分布式系统中跟踪和诊断日志的重要概念。是一个在Java项目中用于日志跟踪的工具&#xff0c;它允许你在多线程环境下关联和传递特定的上下文信息。 MDC是一…

金三银四面试题(十七):MySQL面试都问什么(2)

今天我们继续盘点那些高频的MySQL面试题。 说说InnoDB与MyISAM的区别 InnoDB 支持事务&#xff0c;MyISAM 不支持&#xff0c;对于InnoDB 每一条SQL 语言都默认封装成事务&#xff0c;自动提交&#xff0c;这样会影响速度&#xff0c;所以最好把多条SQL 语言放在begin 和comm…

Java 二叉数(1)

一、认识树 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。它具有以下的特点&#xff1a; 有一个特殊的…

react-router-dom+history路由跳转白屏需手动刷新才显示

搭建一个新项目&#xff0c;路由照常配好了&#xff0c;但是很奇怪&#xff0c;跳转的时候第一次白屏&#xff0c;<root></root>里面只有一个,号&#xff0c;页面是空白的&#xff0c;再手动刷新才显示内容&#xff0c;检查了路由很多遍&#xff0c;也看了地址栏都…

javascript密码验证规则,数字、字母、特殊符号两种以上

在验证密码复杂的正则表达试中&#xff0c;几位码友有发布过从两种字符里选两种的&#xff0c;从三种字符里选有三种的。 今天我提一个从三种里选两种的。有喜欢的朋友拿去用。 密码须包含数字、字母、特殊符号两种以上&#xff0c;且不少于8位&#xff0c;不多于32位。 pass…

IDEA中的Debug功能介绍

说明&#xff1a;本文介绍IDEA中的Debug功能&#xff0c;基于2023.2&#xff08;Ultimate Edition&#xff09;版本 简单介绍 首先&#xff0c;在程序需要停止的所在行号上&#xff0c;鼠标左键&#xff0c;可设置一个断点&#xff0c;是一个红色圆点标志&#xff0c;表示程序…

2024年腾讯云优惠券领取步骤使用教程详解

随着云计算技术的快速发展&#xff0c;越来越多的企业和个人开始选择使用云服务来提升自己的业务能力和工作效率。腾讯云作为国内领先的云服务提供商&#xff0c;其优质的服务和丰富的资源吸引了大量的用户。为了回馈广大用户&#xff0c;腾讯云经常会推出各种优惠活动&#xf…

nfs部署--相关记录

以下是在 CentOS 8 中将 10.40.111.41 上的 /nfsdata 目录通过 NFS 共享到 10.40.111.43 和 10.40.111.45 的 /nfsdata 目录的详细步骤&#xff1a; 在 10.40.111.41 上操作&#xff1a; 安装并配置 NFS 服务器&#xff1a; a. 安装 NFS 服务器软件包&#xff1a; sudo dnf in…

【b站李同学的Lee】2 Git进阶【gitgithub】入门教程,必学!

课程地址&#xff1a;【【git&github】入门教程&#xff0c;必学&#xff01;】 https://www.bilibili.com/video/BV1cE411G7yc/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 2 Git进阶 2.1 分支 2.1.1 分支细分 2.1.2 分支命令 1查看…

LeetCode-热题100:148. 排序链表

题目描述 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a; head [4,2,1,3] 输出&#xff1a; [1,2,3,4] 示例 2&#xff1a; 输入&#xff1a; head [-1,5,3,4,0] 输出&#xff1a; [-1,0,3,4,5] 示例…

vue 和 react 的区别

不同点 vue vue 把 html、css、js写到一个文件中&#xff0c;逻辑更加清楚vue 使用了模版系统&#xff0c;提供了模版引擎处理响应式&#xff0c;数据的双向绑定&#xff0c;但是也是单向数据流更易于上手 react 使用 jsx 语法&#xff0c;允许我们在 js 中书协 html 代码…

unity学习(83)——细节名称和血条

眼中有细节&#xff0c;学习的过程才能平稳&#xff01; 1.游戏更新时把名字也更新 代码如下&#xff1a; 效果如下&#xff1a; 2.因为是第三人称&#xff0c;从背后看&#xff0c;所以名称应该水平对称&#xff0c;翻转一下&#xff01;rotate y180 游戏内效果如下&#xf…

升级xcode15 报错Error (Xcode): Cycle inside Runner

升级xcode15后报错 Could not build the precompiled application for the device. Error (Xcode): Cycle inside Runner; building could produce unreliable results. This usually can be resolved by moving the shell script phase Thin Binary so that it runs before th…

Python程序设计 列表

教学案例八 列表 1. 计算并显示斐波那契数列 输入n,计算并显示斐波那契数列前n项.一行打印5项&#xff0c;每项显示宽度为6 什么是斐波那契数列 斐波那契数列&#xff08;Fibonacci sequence&#xff09;&#xff0c;又称黄金分割数列、 因数学家莱昂纳多斐波那契&#xff…

vue动态绑定class的几种方法

一、对象语法 1、给v-bind:class 设置一个对象&#xff0c;可以动态地切换class&#xff0c;例如&#xff1a; <div id"app"><div :class"{active:isActive}"></div> </div> <script> var app new Vue({el:#app,data:{isA…

FreeRTOS任务切换学习

FreeRTOS任务切换学习 所谓任务切换&#xff0c;就是CPU寄存器的切换。假设当由任务A切换到任务B时&#xff0c;主要分为两步&#xff1a; 1&#xff1a;需暂停任务A的执行&#xff0c;并将此时任务A的寄存器保存到任务堆栈&#xff0c;这个过程叫做保存现场&#xff1b; 2&am…

【无标题】系统思考—心智模式

“直到你使无意识变为有意识&#xff0c;它将指导你的生活并且你会称之为命运。”—卡尔荣格 心智模式深藏于我们内心之中&#xff0c;它潜移默化地影响着我们对世界的理解和判断。往往这些影响是如此隐蔽&#xff0c;以至于我们自己都未必察觉到是什么在驱动我们的选择、决策…

【Entity Framework】聊聊EF中键

【Entity Framework】聊聊EF中键 文章目录 【Entity Framework】聊聊EF中键一、概述二、配置主键2.1 约定配置主键2.2 单个属性配置为实体主键2.3 组合主键 三、主键名称四、键类型和值五、备用键 一、概述 键用作每个实体实例的唯一标识符。EF中的大多数实体都有一个键&#…

线程池阻塞队列的选择

一、背景 想起前两年被问到阻塞队列怎么选&#xff0c;有界是必然的&#xff0c; ArrayBlockingQueue、LinkedBlockingQueue怎么选呢。 二、打开源码看看 ArrayBlockingQueue arrayBlockingQueue new ArrayBlockingQueue(3);LinkedBlockingQueue linkedBlockingQueue new Lin…

VPP 负载均衡测试代码

1. 均衡的测试思想和流程说明。 先说一下理论&#xff0c; 然后后边才知道 代码逻辑。 调试了两天&#xff0c;这个代码终于通了。 由于时间关系&#xff0c; 画了一个粗略的图。另外这个代码只是流程通了&#xff0c;不过要帮助理解负载均衡我认为已经足够了。 下面是windo…