# Rembg: Unauthenticated SAM model injection permits local-file disclosure through malicious ONNX graphs

Unauthenticated extras.sam_model path traversal in rembg's /api/remove lets attacker plant malicious ONNX models that exfiltrate local files via returned PNG masks.

- Payout: Research
- Severity: high
- Program: rembg
- Found by: rach1tarora
- Disclosed: 2026-10-27
- CVE: CVE-2026-115924
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-qr6x-7v33-6qmg
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-qr6x-7v33-6qmg
- Tags: area:ai domain:ai domain:web impact:data-leak kind:research platform:ghsa sev:high tech:python technique:chained technique:source-review vuln:info-disclosure vuln:path-traversal

**Target:** rembg HTTP API /api/remove SAM model loading (pooch.retrieve)
**Root cause:** Attacker-controlled extras.sam_model is interpolated into SAM encoder/decoder filenames and GitHub download URLs; pooch.retrieve() is called without a pinned hash and creates attacker-selected parent directories without cache containment. A URL fragment is stripped by requests but retained in the local POSIX path, letting the attacker place a malicious ONNX model beside a target file.
**Steps:**
1. Send unauthenticated POST to `/api/remove` with `extras.sam_model` containing path traversal plus a URL `#fragment`; first request primes the path tree and returns HTTP 500.
2. Resend the identical request; pooch downloads the attacker asset twice and stores it as both SAM encoder and decoder models beside the target file.
3. The malicious ONNX graph uses a relative external tensor to read the target file and maps each byte to mask pixels.
4. rembg returns the mask as a PNG; attacker decodes the PNG back into the original file bytes.
**How found:** Reporter noticed sam_model flows from public extras JSON into SAM filenames and fixed GitHub URLs, and that requests strips URL fragments while the local POSIX path keeps them, allowing directory placement; then built a malicious ONNX graph to abuse external-data loading.
**Exploitation:** Unauthenticated attacker supplies a crafted sam_model value; the first request creates directories (HTTP 500), the second downloads the malicious ONNX model twice into the target directory. The model reads a chosen local file as ONNX external data and encodes its bytes into the returned mask PNG, which the attacker decodes offline. PoC disclosed /flag and /etc/passwd (839 bytes) in a root-running container.
**Insight:** When a user-controlled string becomes both a download URL and a local cache filename, test fragment/query stripping differences between the HTTP client and the filesystem path — the fragment survives locally and can redirect where pooch writes. Also check whether model loaders honor ONNX external-data relative paths, turning model placement into arbitrary file read.

