GitHub Security Advisory: GHSA-rqgh-gxv4-6657
Package: github.com/gotenberg/gotenberg/v8 (GO)
Severity: CRITICAL (CVSS 9.8)
CWE: CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Vulnerable versions: = 8.29.1
Patched in: unpatched

Summary: Gotenberg has Unauthenticated RCE via ExifTool Metadata Key Injection

Details:
# Unauthenticated RCE in Gotenberg via Metadata Key Newline Injection

## Summary

Gotenberg's `/forms/pdfengines/metadata/write` HTTP endpoint accepts a JSON metadata object and passes its keys directly to ExifTool via the go-exiftool library. No validation is performed on key characters. A `\n` embedded in a JSON key splits the ExifTool stdin stream into a new argument line, allowing an attacker to inject arbitrary ExifTool flags — including `-if`, which evaluates Perl expressions. This achieves unauthenticated OS command execution in a single HTTP request. The response is HTTP 200 with a valid PDF, making the attack transparent to basic monitoring.

## Vulnerability Details

| Field            | Value                                    |
|------------------|------------------------------------------|
| Product          | Gotenberg                                |
| Version          | 8.29.1 (default `gotenberg/gotenberg:8`) |
| Component        | `pdfengines/metadata/write` endpoint     |
| CWE              | CWE-78 — Improper Neutralization of Special Elements used in an OS Command |

## Affected Code

**Product:** Gotenberg  
**Endpoint:** `/forms/pdfengines/metadata/write`  
**Root cause:** JSON metadata keys are passed to go-exiftool without control-character
validation. The existing `dangerousTags` blocklist uses exact-match deletion and
provides no defense against `\n`-embedded keys.

The injection occurs because go-exiftool writes each key to ExifTool's stdin as:

```go
fmt.Fprintln(e.stdin, "-"+k+"="+str)   // k contains \n → splits into a new argument line
```

When `k` is `Title\n-if\nsystem('cmd')||1\n-Comment`, ExifTool's stdin becomes:

```
-Title
-if
system('cmd')||1
-Comment=x
```

ExifTool's `-if` flag evaluates its argument as a Perl expression, giving the attacker arbitrary code execution.

**Why it's vulnerable:** Gotenberg is the HTTP entry point. It controls what data enters go-exiftool. The `dangerousTags` blocklist (`FileName`, `Directory`) shows that the authors are aware that certain keys are dangerous, but the fix is incomplete: it uses exact string matching and does not strip or reject control characters in keys.
This vulnerability exists entirely within Gotenberg's responsibility and is independently fixable without changing go-exiftool.

## Attack Scenario

**Threat actor:** Unauthenticated remote attacker  
**Preconditions:** Gotenberg port 3000 is reachable (common in internal/cloud deployments)  

1. Attacker sends a POST request to `/forms/pdfengines/metadata/write` with any valid PDF and a metadata JSON object whose key contains embedded newlines.
2. Gotenberg deserializes the JSON key — `\n` is preserved as a literal newline in Go's  `map[string]any` after `json.Unmarshal`.
3. The key is forwarded to go-exiftool, which writes it verbatim to ExifTool's stdin, splitting it across multiple argument lines.
4. ExifTool processes `-if system('cmd')||1` as a Perl expression and executes `cmd`.
5. The attacker exfilt