Researchers Detail Code Execution Vulnerability in Popular PDF Viewer, PDF.js
Security researchers from Codean Labs published the technical details and a proof-of-concept (PoC) exploit code for a high-severity CVE-2024-4367 vulnerability that has been discovered in PDF.js, a widely used JavaScript-based PDF viewer maintained by Mozilla. The vulnerability allows attackers to execute arbitrary JavaScript code upon the opening of a malicious PDF file. This flaw affects all Firefox users running versions below 126, as well as numerous web- and Electron-based applications that utilize PDF.js for preview functionality.
PDF.js serves two primary purposes: it is the built-in PDF viewer for Firefox, and it is bundled into a Node module called pdfjs-dist, which sees approximately 2.7 million weekly downloads according to NPM. Websites and applications, including those for Git-hosting platforms and note-taking, use PDF.js to provide embedded PDF preview functionality.
This vulnerability does not stem from the PDF format’s scripting functionality but from a specific part of the font rendering code. In PDF.js, a path generator function is pre-compiled for every glyph to optimize performance. This involves creating a JavaScript Function object with instructions that describe the glyph’s path.
The vulnerability arises when the cmds array, which generates the Function body, can be manipulated to insert arbitrary code. Specifically, the fontMatrix array, which should contain only numeric values, can be controlled through a PDF’s metadata to include strings. This string insertion can lead to arbitrary JavaScript code execution when the glyph is rendered.
The exploit works by carefully crafting the fontMatrix array in the PDF’s metadata. For example, inserting a string like 0\); alert\(‘foobar’) into the matrix can trigger an alert when the PDF is opened. The code executes in the context of PDF.js, which runs under the origin resource://pdf.js. This prevents access to local files but allows certain privileged actions, such as invoking file downloads or accessing the real path of the opened PDF file.
In applications embedding PDF.js, this vulnerability can lead to severe consequences. An attacker could gain an XSS primitive on the domain hosting the PDF viewer, potentially resulting in data leaks, unauthorized actions, or even full account takeovers. In Electron apps without proper sandboxing, the vulnerability can escalate to native code execution, posing an even greater risk. You can find a proof-of-concept PDF file here.
To mitigate the risk posed by CVE-2024-4367, developers should update PDF.js to version 4.2.67 or higher. Many wrapper libraries, such as react-pdf, have also released patched versions. Developers are advised to check their node_modules folder for any instances of pdf.js to ensure all embedded versions are updated.
Additionally, disabling the isEvalSupported setting in PDF.js can prevent the vulnerable code path from being executed. Implementing a strict content security policy that disallows eval and the Function constructor can also mitigate the vulnerability.