CVE-2025-27089
Executive Summary
CVE-2025-27089 is a medium-severity authorization bypass vulnerability in Directus, a real-time API and App dashboard for managing SQL database content. The flaw allows users with multiple overlapping policies to update a superset of fields, potentially including sensitive fields like passwords, beyond what any single policy permits. The vulnerability arises from the permission engine’s failure to evaluate field-level access per item when multiple policies apply. The fix in version 11.1.2 introduces field-level permission checks in the database query, ensuring that only permitted fields are updated for each item.
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.
No signup required
Supply Chain & Package Security
Directus is distributed as an npm package (directus). Users should verify the integrity of the package using checksums or signatures provided by the maintainer. The vulnerability affects all versions prior to 11.1.2. Organizations using Directus in their supply chain should audit their dependencies and update to the patched version immediately.
CVSS Breakdown & Threat Level
- CVSS Score: 5.4 (Medium)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: Low (PR:L)
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: None (C:N)
- Integrity Impact: Low (I:L)
- Availability Impact: Low (A:L)
The vulnerability requires authenticated access with at least one policy granting update permissions. The impact is limited to unauthorized field updates, potentially affecting data integrity.
Deep Dive & Mechanics
The vulnerability exists in Directus’s permission engine when handling overlapping policies. In Directus, policies define access rules for actions (e.g., update) on specific fields, often with conditions (e.g., id == 1). When a user has multiple policies, the engine incorrectly computes the union of allowed fields across all policies, rather than evaluating each policy’s field restrictions per item.
For example:
- Policy A: Allows update to
field_aifid == 1 - Policy B: Allows update to
field_bifid == 2
A user with both policies can update both field_a and field_b on items with id == 1 or id == 2, even though each policy only permits one field. This can lead to unauthorized updates to sensitive fields like password if a policy grants access to it under certain conditions.
The root cause is in the validateItemAccess function, which previously only verified item-level access (whether the user can update the item at all) without checking field-level permissions. The fix modifies the database query to return a flag (1 or null) for each requested field, indicating whether the user has access. The final check ensures that all requested fields have access permissions for the returned items.
Vulnerable vs. Patched Code
Vulnerable Code (Pre-11.1.2):
// Simplified example of permission check
function validateItemAccess(item, fields, policies) {
// Only checks if user can update the item
const hasAccess = policies.some(policy => policy.allowsUpdate(item));
if (!hasAccess) throw new Error('Access denied');
// No field-level check
return item;
}
Patched Code (11.1.2):
// Simplified example of patched permission check
function validateItemAccess(item, fields, policies) {
// For each field, check if any policy grants access
const fieldAccess = {};
for (const field of fields) {
fieldAccess[field] = policies.some(policy => policy.allowsUpdateField(item, field));
}
// Ensure all requested fields have access
const allFieldsAccessible = fields.every(field => fieldAccess[field]);
if (!allFieldsAccessible) throw new Error('Access denied to one or more fields');
return item;
}
The patched version uses a CASE/WHEN mechanism in the SQL query to return flags instead of actual values, preventing data leakage while enforcing field-level permissions.
Exploitation & Lab Setup
Red Team
Prerequisites:
- Access to a Directus instance (version < 11.1.2)
- Authenticated user with at least two policies that grant update access to different fields with different conditions
Exploitation Steps:
- Identify two policies:
- Policy A: Allows update to
emailifid == 1 - Policy B: Allows update to
passwordifid == 2
- Policy A: Allows update to
- Authenticate as a user with both policies.
- Send an update request to
/items/users/1with payload{"email": "attacker@example.com", "password": "newpassword"}. - The server incorrectly allows updating both fields, even though Policy A only permits
emailforid == 1.
Example Request:
PUT /items/users/1 HTTP/1.1
Host: directus.example.com
Authorization: Bearer <token>
Content-Type: application/json
{
"email": "attacker@example.com",
"password": "newpassword"
}
Blue Team
Detection:
- Monitor for update requests to sensitive fields (e.g.,
password,role) from users with multiple policies. - Log and alert on any update to fields that the user’s policies should not permit.
Mitigation:
- Update Directus to version 11.1.2 or later.
- Review and consolidate policies to minimize overlapping permissions.
- Implement additional monitoring for unauthorized field updates.
Indicators of Compromise (IOCs)
- Log Entries: Unusual update requests to sensitive fields (e.g.,
password) from users with limited privileges. - Network Traffic: PUT/PATCH requests to
/items/*endpoints with unexpected field combinations. - Database Changes: Unauthorized modifications to fields like
password,email, orrolein user records.
Detection Engineering
YARA Rule
rule CVE_2025_27089_Directus_Field_Bypass {
meta:
description = "Detects attempts to exploit CVE-2025-27089 in Directus logs"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-27089"
strings:
$s1 = "update" nocase
$s2 = "password" nocase
$s3 = "field_a" nocase
$s4 = "field_b" nocase
condition:
all of ($s1, $s2) or all of ($s1, $s3, $s4)
}
Sigma Rule
title: CVE-2025-27089 - Directus Field Permission Bypass
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to exploit field permission bypass in Directus
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-27089
logsource:
category: application
product: directus
detection:
selection:
action: "update"
fields:
- "password"
- "email"
- "role"
condition: selection
falsepositives:
- Legitimate updates by administrators
level: medium
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-27089 - Directus Field Permission Bypass Attempt";
flow:to_server,established;
content:"PUT"; http_method;
content:"/items/"; http_uri;
content:"password"; http_client_body;
classtype:attempted-admin;
sid:1000001;
rev:1;
)
Remediation & Mitigation
- Immediate Action: Upgrade Directus to version 11.1.2 or later.
- Workaround: No known workarounds exist. The vulnerability is fixed only in the patched version.
- Policy Review: Audit existing policies to minimize overlapping permissions and ensure least privilege.
- Monitoring: Enable detailed logging for update operations and monitor for unauthorized field modifications.
- Access Control: Restrict the number of policies assigned to each user to reduce the risk of permission overlap.
Valters IT
DevSecOps & Cyber Threat Intelligence