A cybersecurity researcher, Zakhar Fedotkin, demonstrated how differences in PDF rendering across various browsers and operating systems can be exploited to manipulate the displayed pricing on PDF invoices.
This vulnerability could significantly impact businesses relying on digital invoices for transactions.
The researcher, inspired by Konstantin Weddige’s blog post “Kobold Letters,” created a proof of concept showing how a PDF invoice could display different prices depending on the viewer used.
Join our free webinar to learn about combating slow DDoS attacks, a major threat today.
In the demonstration, a PDF invoice displayed a total price of £399 when viewed in Safari and MacOS Preview. However, the same file showed a total price of £999 when opened in Google Chrome or Google Drive on a Windows OS.
Fickle PDFs
PDF rendering discrepancies arise because each major browser uses a different engine to render PDF files:
- Google Chrome: Uses PDFium.
- Safari: Employs its own PDF rendering engine.
- Firefox: Utilizes PDF.js.
These engines handle interactive form fields and widget annotations differently, leading to inconsistencies in how the same PDF file is displayed across different platforms.
The researcher used the org.apache.pdfbox Java library to create a hybrid PDF that abuses widget annotations to create rendering discrepancies. The process involves:
- Creating an Interactive Form: The form includes at least one input text field with a default value (e.g., £399).
- Adding Widget Annotations: These annotations are used to render a different value (e.g., £999) in viewers that prioritize annotations over form fields.
Here is a simplified version of the code used:
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();
This discrepancy can lead to severe financial discrepancies if not addressed. For instance, a CEO might approve an invoice based on the £399 displayed in Safari, only for the accounting department to process a payment of £999 after viewing the same invoice in Google Chrome.
The complexity and ambiguity of PDF rendering processes across different platforms require caution when handling digital invoices.
Businesses should ensure that all parties involved in the approval and payment processes use the same PDF viewer to avoid such discrepancies. Additionally, developers and cybersecurity professionals must be aware of these vulnerabilities to safeguard against potential exploitation.
Fickle PDFs examples can be found on the researcher’s GitHub repository for those interested in the technical details and code used in this research.
"Is Your System Under Attack? Try Cynet XDR: Automated Detection & Response for Endpoints, Networks, & Users!"- Free Demo