CVE-2025-30225
Executive Summary
CVE-2025-30225 is a denial-of-service (DoS) vulnerability in the @directus/storage-driver-s3 package, which is a core component of the Directus headless CMS and API platform. The vulnerability allows an unauthenticated attacker to cause a temporary denial of service for all assets served by Directus, including those intended for public and admin users. By sending a burst of malformed image transformation requests, the S3 storage driver enters a state where it returns HTTP 403 (Forbidden) for all subsequent asset requests. This effectively makes all media files inaccessible until the service is restarted or the driver state is cleared. The issue affects Directus versions from 9.22.0 up to (but not including) 11.5.0. The fix was released in Directus 11.5.0, which includes @directus/storage-driver-s3 version 12.0.1.
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
This vulnerability resides in the @directus/storage-driver-s3 npm package. Organizations using Directus should verify their dependency tree to ensure they are not using a vulnerable version of this package. The package is a direct dependency of Directus core and is responsible for handling all S3-compatible storage operations, including image transformations. A supply chain attack could exploit this vulnerability if a malicious actor were to introduce a similar flaw into a forked or mirrored version of the package. Regular dependency auditing and integrity verification are recommended.
CVSS Breakdown & Threat Level
- CVSS Score: 5.3 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
- Attack Vector (AV): Network – The vulnerability can be exploited remotely over the network.
- Attack Complexity (AC): Low – No special conditions or complex attack sequences are required.
- Privileges Required (PR): None – No authentication is needed to trigger the DoS.
- User Interaction (UI): None – The attacker does not need to trick a legitimate user.
- Scope (S): Unchanged – The vulnerable component and the affected assets are within the same security authority.
- Confidentiality (C): None – No data is exposed.
- Integrity (I): None – No data is modified.
- Availability (A): Low – The attack causes a temporary denial of service for assets, but the system itself remains operational.
Threat Level: Medium. While the CVSS score is moderate, the impact on availability can be significant for production environments that rely on Directus for serving media assets. The low attack complexity and lack of authentication requirements make it an attractive target for disruption.
Deep Dive & Mechanics
The vulnerability is rooted in how the @directus/storage-driver-s3 package handles image transformation requests. Directus allows users to request transformed versions of images (e.g., resizing, cropping) via URL parameters. These transformations are processed on-the-fly by the S3 driver.
When a malformed transformation request is made (e.g., invalid dimensions, unsupported format, or corrupted parameters), the driver attempts to process it. Under normal circumstances, a single malformed request results in an error response. However, when a large number of such requests are sent simultaneously (a "burst"), the driver's internal state management fails. Specifically, the driver appears to accumulate error states or exhaust a resource (such as file handles, memory, or a rate limiter) that is not properly reset. Once this threshold is crossed, the driver enters a degraded mode where it returns HTTP 403 for all subsequent asset requests, regardless of whether they are valid or not.
The root cause is a lack of proper resource allocation limits and error handling in the transformation pipeline. The driver does not throttle or reject malformed requests early enough, allowing an attacker to exhaust a shared resource. The fix in version 12.0.1 likely introduces input validation, rate limiting, or a circuit breaker pattern to prevent this state from being reached.
Vulnerable vs. Patched Code
The exact code changes are not publicly available, but based on the advisory, the fix addresses the resource exhaustion issue. A conceptual comparison is provided below.
Vulnerable Code (Conceptual):
// Vulnerable: No limit on concurrent malformed transformations
async function handleTransformation(request) {
// Assume request is malformed
try {
const result = await processTransformation(request);
return result;
} catch (error) {
// Error is logged but state is not cleaned up
console.error('Transformation failed:', error);
// Resource (e.g., file handle) may not be released
return { status: 400, body: 'Bad Request' };
}
}
Patched Code (Conceptual):
// Patched: Added rate limiting and resource cleanup
const rateLimiter = new RateLimiter({ max: 100, windowMs: 60000 });
async function handleTransformation(request) {
// Rate limit check
if (!rateLimiter.allow(request.ip)) {
return { status: 429, body: 'Too Many Requests' };
}
// Input validation
if (!isValidTransformation(request)) {
return { status: 400, body: 'Invalid transformation parameters' };
}
try {
const result = await processTransformation(request);
return result;
} catch (error) {
// Proper cleanup
await cleanupResources(request);
return { status: 400, body: 'Bad Request' };
}
}
Exploitation & Lab Setup
Red Team
Objective: Cause a denial of service for all assets served by Directus.
Prerequisites:
- A target Directus instance (version 9.22.0 to 11.4.x) with S3 storage configured.
- Network access to the Directus API endpoint.
Exploitation Steps:
- Identify the asset endpoint: Typically
https://target.directus.io/assets/<file-id>or similar. - Craft malformed transformation requests: Append invalid transformation parameters to the asset URL. For example:
https://target.directus.io/assets/abc123?width=-1&height=invalid&fit=unknown - Send a burst of requests: Use a tool like
curl,ab, or a custom script to send many such requests concurrently.#!/bin/bash for i in {1..1000}; do curl -s "https://target.directus.io/assets/abc123?width=$RANDOM&height=invalid" & done wait - Verify DoS: After the burst, attempt to access any asset (even without transformation parameters). The server should return HTTP 403 for all assets.
Expected Outcome: All assets become inaccessible, returning 403 errors. This affects all users, including admins and public visitors.
Blue Team
Detection:
- Monitor for a high volume of HTTP 400 errors from the
/assetsendpoint within a short time window. - Look for requests with unusual or invalid query parameters (e.g., negative numbers, non-numeric values, unknown fit modes).
- Alert on a sudden spike in 403 responses for previously accessible assets.
Mitigation:
- Immediately upgrade to Directus 11.5.0 or later.
- If upgrade is not possible, implement a Web Application Firewall (WAF) rule to block requests with suspicious transformation parameters.
- Rate-limit requests to the
/assetsendpoint per IP address. - Restart the Directus service to clear the driver's degraded state (temporary workaround).
Lab Setup:
- Use Docker to deploy a vulnerable Directus instance:
version: '3' services: directus: image: directus/directus:10.0.0 ports: - "8055:8055" environment: DB_CLIENT: 'sqlite3' DB_FILENAME: '/directus/database/data.db' STORAGE_LOCATIONS: 's3' STORAGE_S3_DRIVER: 's3' STORAGE_S3_KEY: 'your-key' STORAGE_S3_SECRET: 'your-secret' STORAGE_S3_BUCKET: 'your-bucket' STORAGE_S3_REGION: 'us-east-1' - Upload a test image via the Directus admin panel.
- Execute the Red Team steps above to trigger the vulnerability.
Indicators of Compromise (IOCs)
Network IOCs:
- High volume of HTTP requests to
/assets/*with malformed query parameters (e.g.,width=-1,height=abc,fit=unknown). - Sudden increase in HTTP 403 responses from the Directus server for previously accessible assets.
- Repeated requests from a single IP address to the same asset with varying invalid parameters.
- High volume of HTTP requests to
Log IOCs:
- Directus logs showing repeated
Transformation failederrors followed by403 Forbiddenresponses. - Application logs indicating resource exhaustion (e.g.,
ENFILE,EMFILE, orOut of memoryerrors).
- Directus logs showing repeated
File System IOCs:
- Temporary files in the S3 cache directory that are not cleaned up (if applicable).
Detection Engineering
YARA Rule
rule CVE_2025_30225_Directus_S3_DoS {
meta:
description = "Detects malformed transformation requests targeting Directus S3 storage driver"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-30225"
severity = "medium"
strings:
$s1 = "/assets/" ascii wide nocase
$s2 = "width=" ascii wide nocase
$s3 = "height=" ascii wide nocase
$s4 = "fit=" ascii wide nocase
$bad_param1 = /width=-\d+/ ascii wide
$bad_param2 = /height=[^0-9]/ ascii wide
$bad_param3 = /fit=(?!cover|contain|inside|outside)[a-z]+/ ascii wide
condition:
all of ($s1, $s2, $s3, $s4) and any of ($bad_param1, $bad_param2, $bad_param3)
}
Sigma Rule
title: CVE-2025-30225 - Directus S3 Storage Driver DoS via Malformed Transformations
id: 8a4b3c2d-1e5f-6a7b-8c9d-0e1f2a3b4c5d
status: experimental
description: Detects a burst of malformed image transformation requests to Directus assets endpoint, indicating exploitation of CVE-2025-30225.
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-30225
logsource:
category: webserver
product: directus
detection:
selection:
http.method: GET
http.url|contains: '/assets/'
http.url|contains|any:
- 'width=-'
- 'height=abc'
- 'fit=unknown'
condition: selection
falsepositives:
- Legitimate but rare malformed requests from automated tools
level: medium
tags:
- attack.t1499
- cve.2025.30225
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-30225 - Directus S3 DoS via Malformed Transformations"; flow:to_server; content:"/assets/"; http_uri; pcre:"/(width=-\d+|height=[^0-9]|fit=(?!cover|contain|inside|outside)[a-z]+)/i"; classtype:denial-of-service; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade Directus: Update to version 11.5.0 or later. This includes the patched
@directus/storage-driver-s312.0.1.npm install directus@latest - Restart Service: If an immediate upgrade is not possible, restart the Directus service to clear the driver's degraded state. This is a temporary fix.
- Implement Rate Limiting: Use a reverse proxy (e.g., Nginx, HAProxy) or WAF to rate-limit requests to the
/assetsendpoint.limit_req_zone $binary_remote_addr zone=assets:10m rate=10r/s; server { location /assets/ { limit_req zone=assets burst=20 nodelay; proxy_pass http://directus_backend; } } - Input Validation: If you cannot upgrade, add a custom middleware to validate transformation parameters before they reach the S3 driver.
Long-Term Measures:
- Regularly update Directus and all npm dependencies.
- Monitor for unusual patterns in asset request logs.
- Implement a circuit breaker pattern in the storage driver to prevent resource exhaustion.
- Conduct periodic security audits of the Directus deployment.
Workarounds:
- Switch to a different storage driver (e.g., local filesystem) temporarily if S3 is not critical.
- Disable image transformations if not needed (set
TRANSFORMATIONS_ENABLED=falsein environment).
Valters IT
Securing Digital Frontiers