high · 7.7CVE-2026-61835Jul 20, 2026

CVE-2026-61835: Directus SSRF Protection Bypass via 0.0.0.0 in File Import

Rohit Hatagale
AI Security Researcher, SecureLayer7

Directus's file-import feature blocks localhost by IP address, but an attacker can use 0.0.0.0 (which the OS routes to localhost) to slip past the blocklist and read internal services as downloadable

Packagedirectus
Ecosystemnpm
Affected< 12.0.0
Fixed in12.0.0

The problem

Directus exposes a /files/import endpoint that fetches a remote URL and stores the response as a file. To prevent SSRF, it checks the resolved IP against IMPORT_IP_DENY_LIST.

The check in api/src/request/is-denied-ip.ts treats the entry 0.0.0.0 as a special keyword that triggers a scan of local network interfaces. It sets a flag and moves on, so 0.0.0.0 is never placed into the literal blocklist. A subsequent check (IMPORT_IP_DENY_LIST.includes(ip)) therefore passes for the address 0.0.0.0, because it was consumed as a keyword and is absent from the list.

On Linux and macOS the kernel routes 0.0.0.0 to localhost, making this a full-read SSRF. The same gap applies to the IPv6 unspecified address ::.

Proof of concept

A working proof-of-concept for CVE-2026-61835 in directus, with the exact payload below.

http
POST /files/import HTTP/1.1
Host: directus.example.com
Authorization: Bearer <token>
Content-Type: application/json

{
  "url": "http://0.0.0.0:8055/admin",
  "data": {}
}

The vulnerable code path calls env.IMPORT_IP_DENY_LIST.includes('0.0.0.0') as a branch condition to enumerate network interfaces. When that branch is taken, the loop compares each interface address to the resolved IP, but the literal string '0.0.0.0' is never pushed into any blocklist array.

The second guard, IMPORT_IP_DENY_LIST.includes(ip), therefore evaluates to false when ip is '0.0.0.0', allowing the request to proceed.

The fix in commit f75b25fa (PR #27606, v12.0.0) adds explicit blocking of the literal address 0.0.0.0 (and ::) in addition to retaining the network-interface scan logic. Root cause is CWE-918: the address was treated as a configuration keyword rather than a blockable value.

The fix

Upgrade to Directus 12.0.0 or later. The patch (commit f75b25fa44b05c6022b20f231c20bc6e50f021d7, PR #27606) explicitly adds 0.0.0.0 and :: as denied addresses in is-denied-ip.ts, independent of the local-interface scan flag. If you cannot upgrade immediately, add 0.0.0.0 and :: to IMPORT_IP_DENY_LIST manually and ensure your Directus process is network-isolated from sensitive localhost services.

Reporter not attributed.

References: [1][2][3][4][5][6]

Related research