java - 避免公式注入(inject),保留单元格值(HSSF/*.xls 中的引号前缀)

标签 java apache-poi

我正在开发的应用程序使用 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);
        }
    }
}

然后打开生成的文件:

Screenshot to reproduce problem

然后按照以下步骤操作:

  1. 点击 (A) 选择包含恶意内容的单元格
  2. 单击 (B),使光标位于公式编辑器中
  3. 按回车键
  4. 系统将询问您是否允许 Excel 运行外部应用程序;如果您回答是,则启动 Calc(或任何恶意代码)

有人可能会说用户有责任让 Excel 运行任意的东西,并且用户被警告过。但是,Excel 是从受信任的来源下载的,有人可能会落入陷阱。

使用 Excel,您可以在公式编辑器中的文本前面放置一个单引号以将其转义。以编程方式在单元格内容中放置单引号(例如下面的代码)使单引号可见!

String cellValue = cell.getStringCellValue();
if( cellValue != null && "=-+@".indexOf(cellValue.charAt(0)) >= 0 ) {
    cell.setCellValue("'" + cellValue);
}

问题:有没有办法让公式编辑器中的值保持转义,但在单元格中显示正确的值,没有前导单引号?

Desired outcome, when hand-edited with Excel

最佳答案

感谢Axel Richter here的辛勤调查和 Nikos Paraskevopoulos here ....

从 Apache POI 3.16 beta 1 开始(或者对于那些生活危险的人,20161105 之后的任何夜间构建),CellStyle 上有方便的方法对于 getQuotePrefixedsetQuotePrefixed(boolean)

您的代码可能会变成:

// 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);
}

关于java - 避免公式注入(inject),保留单元格值(HSSF/*.xls 中的引号前缀),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40398766/

相关文章:

java - Maven Tycho 相对于 Eclipse PDE 导出 RCP 工具的优势

java - 使用 ServletContext 从外部 war 读取 Hibernate 属性

java - 如何在Java中的textview中显示数组

java - Excel 能够通过修复或删除不可读的内容来打开文件

java - POI 3.17 无法在 weblogic 服务器上运行

java - 无法解析 Spring Controller 中的本地日期时间

java - 如何将两个参数传递给 thymeleaf 模板?

java - 使用 =now() 公式时出现 Apache POI 日期区域设置错误

java - Apache POI 转换器,docx 到 pdf 异常(exception)

java - 通过 Apache POI 读取大型 Excel 文件 (xlsx) 时出错