首发公众号网络研究观,微信搜索关注每日获取更多内容。
网络安全研究员 Zakhar Fedotkin 演示了如何利用不同浏览器和操作系统之间 PDF 渲染的差异来操纵 PDF 发票上显示的价格。
此漏洞可能会严重影响依赖数字发票进行交易的企业。
研究人员受到 Konstantin Weddige 博客文章“Kobold Letters”的启发,创建了一个概念证明。
展示了 PDF 发票如何根据所使用的查看器显示不同的价格。
在演示中,一份 PDF 发票在 Safari 和 MacOS Preview 中显示总价为 399 英镑。
然而,在 Windows 操作系统的 Google Chrome 或 Google Drive 中打开同一份文件时,显示的总价为 999 英镑。
演示过程
变化无常的 PDF
PDF 渲染差异的出现是因为每个主流浏览器使用不同的引擎来渲染 PDF 文件:
-
Google Chrome:使用 PDFium。
-
Safari:采用自己的 PDF 渲染引擎。
-
Firefox:利用PDF.js。
这些引擎以不同的方式处理交互式表单字段和小部件注释,导致同一 PDF 文件在不同平台上的显示方式不一致。
研究人员使用org.apache.pdfbox Java 库创建了一个混合 PDF,该 PDF 滥用小部件注释来造成渲染差异。
该过程包括:
-
创建交互式表单:该表单至少包含一个具有默认值的输入文本字段(例如,399 英镑)。
-
添加小部件注释:这些注释用于在优先考虑注释而不是表单字段的查看器中呈现不同的值(例如,999 英镑)。
PDDocument document = new PDDocument();
PDAcroForm acroForm = new PDAcroForm(document);
PDTextField field = new PDTextField(acroForm);
field.setValue("£399");
// Create and set custom appearance stream
PDFormXObject appearanceStream = new PDFormXObject(document);
PDPageContentStream appearanceContents = new PDPageContentStream(document, appearanceStream);
appearanceContents.beginText();
appearanceContents.showText("£999");
appearanceContents.endText();
appearanceContents.close();
PDAnnotationWidget widget = field.getWidgets().get(0);
widget.setAppearance(appearanceStream);
document.save("Invoice.pdf");
document.close();
如果不加以解决,这种差异可能会导致严重的财务差异。
例如,首席执行官可能会根据 Safari 中显示的 399 英镑批准发票,但会计部门在 Google Chrome 中查看同一张发票后,却处理了 999 英镑的付款。
处理数字发票时,不同平台之间 PDF 渲染过程的复杂性和模糊性要求必须谨慎处理。
企业应确保参与审批和付款流程的所有各方都使用相同的 PDF 查看器,以避免出现此类差异。
此外,开发人员和网络安全专业人员必须意识到这些漏洞,以防止潜在的利用。
对于那些对本研究中使用的技术细节和代码感兴趣的人,可以在研究人员的 GitHub 存储库中找到Fickle PDF 示例。