1、也可以自己编辑,我给大家上传一个方便测试。带脚本的pdf在谷歌文件打开是这样的。
含有脚本的pdf直接使用谷歌或者360浏览器打开,文件地址:
https://download.csdn.net/download/qq_41816505/89448924?spm=1001.2014.3001.5503
2、常用的方法后台可以使用pdfbox禁止此类文件上传(使用的架构若依)。
第一步:pom文件引用依赖jar(新版本也试过,没有这个版本好用,如果有的话,请给我说一下,谢谢)
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.31</version>
</dependency>
2.2、我是在若依架构编码的。
第二步:先编写一个 PdfUtils.java
package com.ruoyi.web.controller.common;
import com.ruoyi.common.utils.uuid.UUID;
import org.apache.pdfbox.io.RandomAccessBufferedFileInputStream;
import org.apache.pdfbox.io.RandomAccessRead;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
public class PdfUtils {
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
/**
* 获取不带扩展名的文件名
*/
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 {
RandomAccessRead is = new RandomAccessBufferedFileInputStream(file);
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;
}
}
第三部在上传的地方加check。
@PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file) throws Exception
{
try
{
//------------------pdf检查------------------------
// 文件后缀
String retfileName = file.getOriginalFilename();
String suffix = retfileName.substring(retfileName.lastIndexOf(".") + 1).toLowerCase();
// 判断是否是pdf文件类型
if (StringUtils.equals(suffix, "pdf")) {
// 判断文件xss攻击
boolean haveJavaScript = PdfUtils.containsJavaScript(PdfUtils.multipartFileToFile(file));
if (haveJavaScript) {
AjaxResult ajax = AjaxResult.error("对不起,您上传的文件[" + retfileName + "]包含xss脚本代码!");
return ajax;
}
}
//------------------end------------------------
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
AjaxResult ajax = AjaxResult.success();
ajax.put("url", url);
ajax.put("fileName", fileName);
ajax.put("newFileName", FileUtils.getName(fileName));
ajax.put("originalFilename", file.getOriginalFilename());
return ajax;
}
catch (Exception e)
{
return AjaxResult.error(e.getMessage());
}
}
最后编码完成后,再次上传带脚本的pdf文件就有错误提示:
下载含有脚本的pdf文件:
https://download.csdn.net/download/qq_41816505/89448924?spm=1001.2014.3001.5503