三尺非寒 发表于 2024-9-5 20:02:06

PDF内带脚本Xss安全测试和整改(若依架构)

1、也可以本身编辑,我给各人上传一个方便测试。带脚本的pdf在谷歌文件打开是这样的。

含有脚本的pdf直接利用谷歌或者360欣赏器打开,文件地点:https://download.csdn.net/download/qq_41816505/89434145?spm=1001.2014.3001.5503

https://img-blog.csdnimg.cn/direct/9430573a15c94d0fb0712d2ed94ff2cc.jpeg
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;
      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/89434145?spm=1001.2014.3001.5503
https://img-blog.csdnimg.cn/direct/b31e9e8af1444452850b843948538158.png


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: PDF内带脚本Xss安全测试和整改(若依架构)