Server-Side XSS in Dynamic PDF
Full command arsenal in the cheatsheetMany applications generate PDF on the fly (invoices, reports, exports) by rendering HTML with a library like wkhtmltopdf, mPDF, dompdf or PhantomJS. If that library interprets HTML and JavaScript and the PDF includes unsanitised user-controlled data, we have a server-side XSS (SSXSS): the injection does not run in the victim's browser but in the server's rendering engine, with access to its context.
Why it is worse than a normal XSS. The converter runs on the server and often allows loading resources with the file:// scheme. A classic XSS steals cookies; this one reads the server's file system. The typical vector is an XMLHttpRequest (or an <iframe>/<embed>) pointing at file://:
<script>
x=new XMLHttpRequest;
x.onload=function(){document.write(this.responseText)};
x.open("GET","file:///etc/passwd");
x.send();
</script>The file content is written into the document and shows up in the generated PDF. If the file causes formatting issues (keys, binaries), wrap it in <pre> to preserve newlines, or encode it with btoa(...) to dump it as Base64 and decode it afterwards.
Common targets. /etc/passwd (confirms users and the flaw), private SSH keys (/home/<user>/.ssh/id_rsa) to jump to an interactive session, config files with credentials, the app's own source code. It can also lead to SSRF (loading internal http://).
How to detect it. Any feature that exports to PDF user-supplied data (name, metadata, comments) is a candidate. Confirm it by putting simple HTML (<b>, <h1>) in a field and checking if it renders in the PDF instead of appearing literal. If the injection point has length limits, look for a less restricted field (a title, a description, some metadata).
Defence. Sanitise/escape all user data before passing it to the converter; disable JavaScript and local-scheme access (file://) in the library config; run the generator in an isolated environment (container with no secrets, no internal network); prefer libraries that treat input as text, not active HTML. Related to local file read as the end goal.
Machines where it's used
- BookHackTheBox