{"id":"CVE-2026-32805","aliases":["GHSA-p799-g7vv-f279","GO-2026-4719"],"url":"https://o3.security/vulnerability/CVE-2026-32805","summary":"Romeo is vulnerable to Archive Slip due to missing checks in sanitization","details":"## Summary\n\nThe `sanitizeArchivePath` function in `webserver/api/v1/decoder.go` (lines 80-88) is vulnerable to a path traversal bypass due to a missing trailing path separator in the `strings.HasPrefix` check. A crafted tar archive can write files outside the intended destination directory.\n\n## Vulnerable Code\n\nFile: `webserver/api/v1/decoder.go`, lines 80-88\n\n```go\nfunc sanitizeArchivePath(d, t string) (v string, err error) {\n\tv = filepath.Join(d, t)\n\tif strings.HasPrefix(v, filepath.Clean(d)) {\n\t\treturn v, nil\n\t}\n\treturn \"\", &ErrPathTainted{\n\t\tPath: t,\n\t}\n}\n```\n\nThe function is called at line 48 inside `[*Decompressor].Unzip`, which is invoked by `Decode` (line 80) during execution of the webserver CLI (command `download`).\n\n## Root Cause\n\n`strings.HasPrefix(v, filepath.Clean(d))` does not append a trailing `/` to the directory prefix, causing a **directory name prefix collision**. If the destination is `/home/user/extract-output` and a tar entry is named `../extract-outputevil/pwned`, the joined path `/home/user/extract-outputevil/pwned` passes the prefix check — it starts with `/home/user/extract-output` — even though it is entirely outside the intended directory.\n\n## Steps to Reproduce\n\n1. **Deploy Romeo**. A measured app writes its coverage data.\n\n2. **Place the PoC zip on the PVC.** Any pod with write access to the `ReadWriteMany` PVC (or the webserver itself) copies a `poc-path-traversal.tar` into the `coverdir` mount path. The archive contains legitimate coverage files alongside two crafted entries with path-traversal names.\n\n3. **Run the webserver CLI against the running webserver:**\n   ```\n   webserver download \\\n     --server http://localhost:8080 \\\n     --directory /home/user/extract-output\n   ```\n\n4. **Observe the bypass.** `unzip` processes the zip stream. For the malicious entries:\n   ```\n   // entry name: ../extract-outputevil/poc-proof.txt\n   filepath.Join(\"/home/user/extract-output\", \"../extract-outputevil/poc-proof.txt\")\n     => \"/home/user/extract-outputevil/poc-proof.txt\"\n\n   strings.HasPrefix(\"/home/user/extract-outputevil/poc-proof.txt\",\n                     \"/home/user/extract-output\")\n     => true   // BUG: prefix collision; file lands OUTSIDE target dir\n   ```\n   Both malicious entries are written outside `/home/user/extract-output/`. The legitimate coverage files land correctly inside it.\n\n## Impact\n\nSuccessful exploitation gives an attacker arbitrary file write on the machine running the webserver CLI. Real-world primitives include:\n\n- Overwriting `~/.bashrc` / `~/.zshrc` / `~/.profile` for RCE on next shell login\n- Appending to `~/.ssh/authorized_keys` for persistent SSH backdoor\n- Dropping a malicious entry into `~/.kube/config` to hijack cluster access\n- Writing crontab entries for persistent scheduled execution\n\nThe attack surface is widened by the default `ReadWriteMany` PVC access mode, which means any pod in the cluster with the PVC mounted can inject the payload — not just the Romeo webserver itself.","published":"2026-03-18T22:24:29.102Z","modified":"2026-08-12T03:51:13.226834690Z","cvss":null,"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Go","name":"github.com/ctfer-io/romeo/webserver","fixedVersion":"0.2.2"}],"fix":{"url":"https://github.com/ctfer-io/romeo/commit/c2ebcfb9f305fd5f6ef68858de82507dbac10263","label":"ctfer-io/romeo@c2ebcfb"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/32xxx/CVE-2026-32805.json"},{"type":"ADVISORY","url":"https://github.com/ctfer-io/romeo/security/advisories/GHSA-p799-g7vv-f279"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-32805"},{"type":"FIX","url":"https://github.com/ctfer-io/romeo/commit/c2ebcfb9f305fd5f6ef68858de82507dbac10263"},{"type":"PACKAGE","url":"https://github.com/ctfer-io/romeo"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:13.226834690Z"}}