# Directus: SSRF Protection Bypass via 0.0.0.0 in File Import

Directus SSRF deny-list treats 0.0.0.0 as a keyword for local interfaces but never blocks the literal address, so file import reaches localhost.

- Payout: Research
- Severity: high
- Program: Directus
- Found by: kakarotsec
- Disclosed: 2026-07-20
- CVE: CVE-2026-61835
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-j5h6-vqc3-phqh
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-j5h6-vqc3-phqh
- Tags: area:web domain:web impact:data-leak impact:internal-access kind:research platform:ghsa sev:high tech:nodejs technique:incomplete-fix technique:source-review vuln:ssrf

**Target:** /files/import URL fetch endpoint (IMPORT_IP_DENY_LIST check)
**Root cause:** is-denied-ip.ts interprets the deny-list entry 0.0.0.0 as a special keyword to block local network interfaces, setting the interface flag and skipping the entry without ever adding the literal 0.0.0.0 address to the blocklist. 0.0.0.0 lies in 0.0.0.0/8, not the blocked 127.0.0.0/8, so it passes as allowed while the OS routes it to localhost.
**Steps:**
1. Authenticate with create permission on `directus_files`.
2. POST to `/files/import` with a URL such as `http://0.0.0.0:8055/` (or an internal service port).
3. Deny-list check passes because 0.0.0.0 is not in the computed blocklist (only 127.0.0.0/8 and interface addresses).
4. Server connects to 0.0.0.0 which resolves to localhost; response body is stored as a downloadable file.
5. Download the file to read the internal service response.
**How found:** Reporter read is-denied-ip.ts and noticed the 0.0.0.0 entry is consumed as a special keyword that sets the network-interface flag and skips to the next entry, so the literal address is never added to the blocklist; then reasoned that 0.0.0.0/8 is distinct from the blocked 127.0.0.0/8 while the OS still routes 0.0.0.0 to localhost.
**Exploitation:** An authenticated user with file-upload rights submits an import URL pointing at 0.0.0.0 on an internal port; the server fetches its own localhost service and stores the response as a file the attacker downloads, yielding full-read SSRF against databases, caches and internal APIs bound to localhost on single-host deployments.
**Insight:** When auditing SSRF deny-lists, check whether sentinel entries like 0.0.0.0 or :: are treated as keywords rather than literal addresses; the unspecified address often routes to localhost at the OS level yet falls outside the loopback CIDR the code actually blocks.

