From XSS to RCE (dompdf 0day)

We discussed this vulnerability as part of our weekly podcast on 22 March 2022

A chain of issues going from an XSS to a remote file download in a server-side PDF renderer, leading to remote-code execution. The XSS initally seemed a bit weak as the application had no secrets or even authentication so attacking other users would not provide much gain. They did notice a feature that would render a PDF for a given page, they could inject HTML that would be rendered into the PDF but not Javascript.

With HTML injection they could inject content, but with a configuration option $isRemoteEnabled the renderer wouldn’t fetch remote file. This setting wasn’t respected for remote fonts downloaded because of an injected font-family src:url(...) CSS rule. These fonts would be downloaded (on versions before 0.8.5) to lib/fonts the filename would be slightly modified in a deterministic way, and the extension would remain unchanged. The file did need to be loadable by php-font-lib but that is all.

So by injecting PHP code into a font’s copyright section, and then navigating to the font’s file directly code execution on the server could be gained.

There are two huge red flags to me here:

  1. Storing everything under the webroot is a bad idea, especially user controlled content.
  2. Storing arbitrary content with an attacker influenced name. In this case they already had a lookup system to find the appropiate font files, so keeping the font names (and extension) is unnecessary. By not giving control of the filename and using a truely random name, even given poor security around the webroot would have made it difficult to exploit.