POI解析dos安全问题分析
POI解析Excel
先来大致看一下传统poi技术的版本以及优缺点对比吧!
首先我们知道POI中我们最熟悉的莫过于WorkBook这样一个接口,我们的POI版本也在更新的同时对这个几口的实现类做了更新:
-
HSSFWorkbook :
这个实现类是我们早期使用最多的对象,它可以操作Excel2003以前(包含2003)的所有Excel版本。在2003以前Excel的版本后缀还是.xls
-
XSSFWorkbook :
这个实现类现在在很多公司都可以发现还在使用,它是操作的Excel2003--Excel2007之间的版本,Excel的扩展名是.xlsx
-
SXSSFWorkbook :
这个实现类是POI3.8之后的版本才有的,它可以操作Excel2007以后的所有版本Excel,扩展名是.xlsx
HSSFWorkbook
它是POI版本中最常用的方式,不过:
-
它的缺点是 最多只能导出 65535行,也就是导出的数据函数超过这个数据就会报错; -
它的优点是 不会报内存溢出。(因为数据量还不到7w所以内存一般都够用,首先你得明确知道这种方式是将数据先读取到内存中,然后再操作)
XSSFWorkbook
-
优点:这种形式的出现是为了突破 HSSFWorkbook
的65535行局限,是为了针对Excel2007版本的1048576行,16384列,最多可以导出104w条数据; -
缺点:伴随的问题来了,虽然导出数据行数增加了好多倍,但是随之而来的内存溢出问题也成了噩梦。因为你所创建的book,Sheet,row,cell等在写入到Excel之前,都是存放在内存中的(这还没有算Excel的一些样式格式等等),可想而知,内存不溢出就有点不科学了!!!
SXSSFWorkbook
从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的SXSSF方式:
优点:
-
这种方式不会一般不会出现内存溢出(它使用了硬盘来换取内存空间, -
也就是当内存中数据达到一定程度这些数据会被持久化到硬盘中存储起来,而内存中存的都是最新的数据), -
并且支持大型Excel文件的创建(存储百万条数据绰绰有余)。
缺点:
-
既然一部分数据持久化到了硬盘中,且不能被查看和访问那么就会导致, -
在同一时间点我们只能访问一定数量的数据,也就是内存中存储的数据; -
sheet.clone()
方法将不再支持,还是因为持久化的原因; -
不再支持对公式的求值,还是因为持久化的原因,在硬盘中的数据没法读取到内存中进行计算; -
在使用模板方式下载数据的时候,不能改动表头,还是因为持久化的问题,写到了硬盘里就不能改变了;
总结:使用XSSFWorkbook
如果没有单独限制大小是很容易受到dos攻击的,使用SXSSFWorkbook不合理也存在dos的风险
SXSSFWorkbook DOS场景描述
使用poi、poi-ooxml第三方开源组件来处理excel文件,实现工作表数量、数据行、数据列等数据读取、写入等操作。提供了HSSF、XSSF以及SXSSF三种方式,使用XSSFWorkbook、SXSSFWorkbook对象进行文件解析处理时:
当调用wb.createSheet()实现新建sheet页签时会创建poi-sxssf-sheetxxxxx.xml临时文件;
调用wb.write(out)向本地磁盘写excel文件时会创建poi-sxssf-template.xlsx临时文件,在该方法仅会删除临时poi-sxssf-template.xlsx文件;
若未调用wb.dispose()方法,过程中产生的临时xml文件未自动清理,高频率请求可导致磁盘Dos攻击;
SXSSFWorkbook wb = new SXSSFWorkbook(100);
Sheet sh = wb.createSheet();
....
// 从临时文件写入Excel 文件
FileOutputStream out = new FileOutputStream("d:\\sxssf.xlsx");
wb.write(out);
out.close();
wb.close(); //关闭Stream closedexcle文档执行操作、更新或读取
//从磁盘删除临时xml文件
wb.dispose();
注意:
除了调用wb.createSheet()实现新建sheet页签时会创建poi-sxssf-sheetxxxxx.xml临时文件外,
SXSSFWorkbook的一些构造方法也会直接创建poi-sxssf-sheetxxxxx.xml临时文件(通常为构造方法参数中包含XSSFWorkbook对象且不为空的才会创建临时xml文件)