CVE-2026-39383 - Gotenberg webhook SSRF
Gotenberg 8.29.1 through 8.30.x can be abused as a blind SSRF primitive
through webhook callbacks. A network attacker who can submit conversion
requests can set Gotenberg-Webhook-Url to an internal or external URL and
cause Gotenberg to POST the converted document there.
The issue is dangerous even when response bodies are not returned to the attacker: POST side effects can be triggered, internal hosts can be probed, and cloud metadata or service endpoints may be reachable from the Gotenberg runtime.
When to use it
Use this recipe when a repository deploys Gotenberg conversion services that accept webhook callback URLs from users, tenants, jobs, or automation. It is designed for source-code/deployment remediation, SSRF egress-boundary review, webhook allow-list enforcement, metadata-service protection, and evidence that conversion requests cannot POST to internal or unapproved endpoints.
Inputs
- Gotenberg version, container/image pins, Helm/compose/Kubernetes manifests, webhook allow-list config, ingress/auth config, and generated dependency or SBOM reports.
- Source/config paths that submit conversion requests, set
Gotenberg-Webhook-Url, define callback hosts, configure egress policy, or expose conversion endpoints to tenants/users. - Regression or deployment checks for patched versions, approved webhook hosts, denied private/link-local/metadata URLs, authenticated conversion access, and safe logging.
- Boundary evidence: allowed callback domains, internal network reachability, metadata endpoints, conversion tenants, logs, image owner, and rollout owner.
Affected versions
- Vulnerable: Gotenberg
>=8.29.1, <8.31.0 - Fixed: Gotenberg
8.31.0+
Indicator-of-exposure
- Gotenberg v8 is deployed in a container image, Helm chart, compose file, or Go module at an affected version.
- Conversion endpoints are reachable from untrusted users or tenants.
- Webhook headers are accepted and no explicit webhook allow-list is configured.
- The runtime can reach private networks, link-local addresses, localhost, or cloud metadata services.
Quick checks:
rg -n "gotenberg|GOTENBERG_API_WEBHOOK|Gotenberg-Webhook-Url|webhook" .
docker image inspect gotenberg/gotenberg:8 --format '{{ index .RepoDigests 0 }}'
go list -m all | rg 'gotenberg/gotenberg'
kubectl get deploy,statefulset,cronjob -A -o yaml | rg -n "gotenberg|WEBHOOK"
Remediation strategy
- Upgrade every Gotenberg deployment to
8.31.0+and pin container images by immutable digest. - Configure
GOTENBERG_API_WEBHOOK_ALLOW_LISTfor approved callback hosts. - Add network egress policy that blocks private ranges, loopback, link-local, and metadata endpoints unless explicitly required.
- Put conversion endpoints behind authentication or a trusted internal ingress while rollout is in progress.
The prompt
You are remediating CVE-2026-39383 (Gotenberg webhook SSRF). Produce exactly
one output:
- A reviewer-ready PR/change request that patches Gotenberg and adds practical
containment controls, or
- TRIAGE.md if this repository does not own a safe patch path.
## Rules
- Scope only CVE-2026-39383.
- Prefer upgrading Gotenberg to `8.31.0+`; do not invent a local fork unless no
vendor-fixed release can be consumed.
- Treat all user-supplied webhook destinations as untrusted.
- Do not auto-merge.
## Steps
1. Inventory all Gotenberg references in manifests, lockfiles, image tags,
Helm values, compose files, Dockerfiles, and deployment docs.
2. Determine whether any deployed version is `>=8.29.1, <8.31.0`.
3. Upgrade affected references to `8.31.0+`; pin container images by digest
where this repo controls deployment artifacts.
4. Add or tighten webhook destination policy:
- prefer `GOTENBERG_API_WEBHOOK_ALLOW_LIST` for known callback hosts;
- add an egress rule denying loopback, RFC1918, link-local, and cloud
metadata addresses from the Gotenberg workload;
- require authentication or trusted ingress for public conversion endpoints.
5. Run the relevant build, dependency, container, and deployment validation.
6. Include a PR body section with affected versions, fixed versions, remaining
operator actions, and any exposure window if the service was internet-facing.
7. Use PR title:
`fix(sec): remediate CVE-2026-39383 in Gotenberg`.
## Stop conditions
- Gotenberg is not present in this repo or deployment source.
- The target platform cannot consume `8.31.0+`.
- Existing tests or deployment rendering fail for unrelated pre-existing
reasons; document them in TRIAGE.md instead of expanding scope.
Output contract
- A reviewer-ready PR or change request that upgrades Gotenberg, pins images, configures webhook allow-lists, adds SSRF/egress validation, and documents exposure/operator review.
- Or a
TRIAGE.mdfile that lists inspected manifests/images/config, owner, observed version, webhook trust boundary, required fix, and residual risk. - The output must include exact validation commands and must not send test callbacks to production internal hosts, metadata services, or sensitive endpoints.
Verification - what the reviewer looks for
- No deployment, lockfile, SBOM, or container reference resolves to vulnerable Gotenberg.
- Webhook destinations are allow-listed or blocked from private/link-local ranges by policy.
- CI, image build, and deployment rendering pass or failures are explicitly called out as pre-existing.
- Publicly reachable deployments have an operator follow-up for exposure review.
Watch for
- Floating image tags such as
gotenberg/gotenberg:8that look patched today but are not reproducible without a digest. - Allow/deny-list variables only documented but not applied to runtime manifests.
- Other Gotenberg
8.31.0advisories in the same rollout, especially CVE-2026-40280 and CVE-2026-40281.
Related recipes
- Source code attack surface map
- Source code secrets and data exposure audit
- OWASP Top 10 2026 audit
- NIST SSDF repository evidence check
References
- GitHub Advisory: https://github.com/advisories/GHSA-5vh4-rgv7-p9g4
- Gotenberg release
v8.31.0: https://github.com/gotenberg/gotenberg/releases/tag/v8.31.0