我正在开发的应用程序使用 Apache POI 创建 Excel 导出。通过安全审计,我们注意到如果用户不够小心,包含恶意值的单元格可能会产生任意进程。
要重现,请运行以下命令:
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
public class BadWorkbookCreator {
public static void main(String[] args) throws Exception {
try(
Workbook wb = new HSSFWorkbook();
FileOutputStream fos = new FileOutputStream("C:/workbook-bad.xls")
) {
Sheet sheet = wb.createSheet("Sheet");
Row row = sheet.createRow(0);
row.createCell(0).setCellValue("Aaaaaaaaaa");
row.createCell(1).setCellValue("-2+3 +cmd|'/C calc'!G20");
wb.write(fos);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后打开生成的文件:
并按照以下步骤操作:
有人可能会说,用户负责让 Excel 运行任意的东西,用户被警告。但是,Excel 是从可信来源下载的,有人可能会落入陷阱。
使用 Excel,您可以在公式编辑器中的文本前放置单引号以将其转义。以编程方式在单元格内容中放置单引号(例如下面的代码)使单引号可见!
String cellValue = cell.getStringCellValue();
if( cellValue != null && "=-+@".indexOf(cellValue.charAt(0)) >= 0 ) {
cell.setCellValue("'" + cellValue);
}
Run Code Online (Sandbox Code Playgroud)
问题:有没有办法在公式编辑器中保持值转义,但在单元格中显示正确的值,没有前导单引号?
感谢这里的Axel Richter和这里的Nikos Paraskevopoulos的辛勤工作......
Apache的POI 3.16测试版1日起(或为那些谁住危险,20161105之后的任何每晚构建),上有方便的方法CellStyle为getQuotePrefixed和setQuotePrefixed(布尔)
您的代码可能会变成:
// Do this once for the workbook
CellStyle safeFormulaStyle = workbook.createCellStyle();
safeFormulaStyle.setQuotePrefixed(true);
// Per cell
String cellValue = cell.getStringCellValue();
if( cellValue != null && "=-+@".indexOf(cellValue.charAt(0)) >= 0 ) {
cell.setCellStyle(safeFormulaStyle);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6800 次 |
| 最近记录: |