Aug 7, 2026·6 min read·0 visits
Missing authorization in Craft CMS ChartsController allowed unauthorized access to sensitive time-series user metrics and registration demographics via `/actions/charts/get-new-users-data` prior to versions 4.18.1 and 5.10.3.
An authorization bypass vulnerability in Craft CMS allows unauthenticated or low-privileged users to query and obtain sensitive time-series user registration counts and demographic metrics. This is due to a missing authorization check inside the actionGetNewUsersData endpoint of the ChartsController class.
Craft CMS features an administrative dashboard containing visual metric components designed to provide administrators with quick insights into site usage. The ChartsController class coordinates data retrieval for these components. Under standard operations, charts display metadata such as user registrations, system activity, and asset counts. This data retrieval operates via specified action endpoints, which handle POST requests with structured query parameters.
Historically, user-related actions in Craft CMS are bound by authorization checks. Access to user directories, groups, and growth metrics should be restricted to users possessing the viewUsers permission. However, the endpoint /actions/charts/get-new-users-data did not validate if requests were initiated from within the authorized Control Panel context or by a user with explicit privileges.
The lack of validation exposed a vulnerable attack surface. An attacker with standard authenticated access could query this endpoint directly. The resulting response disclosed time-series registration metrics and user group distribution patterns, circumventing intended security constraints.
The fundamental issue stems from a missing authorization context check inside ChartsController::actionGetNewUsersData(). Craft CMS allows routing to controller actions via specific frontend action parameters or backend Control Panel routes. If a controller action fails to explicitly assert its routing domain, it may remain accessible to frontend actions.
In the vulnerable codebase, actionGetNewUsersData() accepted inbound requests without verifying that they originated from the Control Panel (requireCpRequest()). Consequently, the action was exposed on the public-facing interface to any authenticated user session, bypassing the restrictive access controls defined for the Control Panel directory.
Furthermore, the action failed to enforce the explicit viewUsers permission. In multi-tenant or role-restricted environments, users are often assigned low-privilege roles, such as "Content Editor". These roles are granted base Control Panel access (accessCp) but are restricted from accessing user administration features. The absent permission validation allowed these restricted accounts to directly query the database for registration statistics.
To understand the flaw, we analyze the implementation of actionGetNewUsersData within src/controllers/ChartsController.php. Prior to the security patch, the method immediately extracted request parameters without verifying the origin of the route or the privileges of the active session.
// Vulnerable Code Path
public function actionGetNewUsersData(): Response
{
// Missing: $this->requireCpRequest() or explicit permission checks
$userGroupId = $this->request->getBodyParam('userGroupId');
$startDateParam = $this->request->getRequiredBodyParam('startDate');
$endDateParam = $this->request->getRequiredBodyParam('endDate');
// ... execution of user query ...
}The remediation committed in 9ee53efc1314e6aba32771c66a13e072a246f4ce introduced a validation call at the entry point of the controller action. By calling $this->requireCpRequest(), the application now verifies that the request context matches the admin Control Panel.
// Patched Code Path
public function actionGetNewUsersData(): Response
{
// Verifies the request originates from the Control Panel context
$this->requireCpRequest();
$userGroupId = $this->request->getBodyParam('userGroupId');
$startDateParam = $this->request->getRequiredBodyParam('startDate');
$endDateParam = $this->request->getRequiredBodyParam('endDate');
// ... execution of user query ...
}While this patch blocks unauthenticated external requests and frontend-only users, a minor residual gap remains. The call to requireCpRequest() does not validate the specific viewUsers permission. Control Panel users with minimal privileges (accessCp only) can still access the route. If a deployment relies on granular user group isolation, these low-privilege users can query stats about other user groups, though direct PII is not leaked.
Exploitation requires a valid session on the target application. This session can belong to a low-privileged user possessing basic Control Panel privileges. The attacker first authenticates and extracts the active CSRF token (CRAFT_CSRF_TOKEN) from the document object model.
The attacker then constructs a structured HTTP POST request to the action endpoint. The request payload must include valid startDate and endDate parameters, alongside an optional userGroupId parameter. Specifying different IDs allows the attacker to query registration statistics for specific target user groups sequentially.
curl -X POST "https://example.com/actions/charts/get-new-users-data" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Cookie: CraftSessionId=9ee53efc1314e6aba32771c66a13e0" \
--data-urlencode "CRAFT_CSRF_TOKEN=abc123xyz" \
--data-urlencode "startDate=2026-01-01" \
--data-urlencode "endDate=2026-12-31" \
--data-urlencode "userGroupId=2"Upon execution, the server processes the database query and returns a JSON response containing the registration counts grouped chronologically. This response leaks aggregate site metrics. An attacker can use this data to perform reconnaissance, mapping user registration trends and estimating the sizes of internal user groups.
The immediate impact of this vulnerability is unauthorized information disclosure. While the endpoint does not leak high-severity sensitive data like plaintext credentials, password hashes, or full names, it exposes system-wide user growth data. An attacker can determine historical user sign-up patterns and estimate platform adoption rates.
In enterprise and multi-tenant environments, user demographics and registration velocity constitute proprietary business intelligence. For instance, an unauthorized competitor with low-privileged access could map active growth cycles. Additionally, mapping specific user group IDs allows attackers to assess which administrative or standard groups are actively expanding.
The vulnerability represents a failure in depth-of-defense design. It illustrates how standard controller endpoints can accidentally expose sensitive data metrics if authorization checks are only enforced at the UI layer rather than the API layer. Remediation is required to maintain complete data confidentiality across role-based access control policies.
Administrators should immediately deploy updated packages. For installations running the 4.x branch, upgrade to version 4.18.1 or higher. For installations running the 5.x branch, upgrade to version 5.10.3 or higher. These releases implement the necessary request context verification.
If immediate patching is not feasible, restrict route access at the web server layer. WAF rules can block incoming requests to /actions/charts/get-new-users-data or equivalent rewrite patterns if they originate from unauthorized IP ranges or lack admin session cookies. However, patching via Composer remains the recommended path.
To detect previous exploitation attempts, review application logs for POST requests directed to the target action path. Pay particular attention to requests submitted by users who lack administrative rights. Correlating these requests with user group IDs in the query payload helps identify unauthorized intelligence-gathering activities.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Craft CMS Pixel & Tonic | >= 4.0.0-RC1, < 4.18.1 | 4.18.1 |
Craft CMS Pixel & Tonic | >= 5.0.0-RC1, < 5.10.3 | 5.10.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862 |
| Attack Vector | Network |
| CVSS | 5.3 (Medium) |
| Exploit Status | poc |
| KEV Status | Not Listed |
The application does not perform an authorization check when an actor attempts to access the actionGetNewUsersData resource.
An authenticated information disclosure vulnerability in Craft CMS allows high-privilege administrators to extract sensitive environment variables, including the CRAFT_SECURITY_KEY and database credentials, using a blind error-based template injection attack within element select condition rules.
A protocol-parsing vulnerability in the pure-Python HTTP/2 library 'h2' (versions <= 4.4.0) allows unauthenticated remote attackers to perform HTTP Request Smuggling (CWE-444). The vulnerability exists because the library does not validate the uniqueness of 'Host' headers in incoming HTTP/2 request streams. When an upstream gateway parses such requests and downgrades them to HTTP/1.1 for internal backend servers, the resulting stream contains duplicate Host headers, which leads to parsing inconsistency and potential bypass of security filters.
An information disclosure vulnerability in Craft CMS allows users with administrative or non-sandboxed template-authoring privileges to read arbitrary system and configuration files. The issue stems from an incomplete class instantiation blocklist in the Twig template extension, which omitted PHP's built-in SplFileObject class.
An authorization bypass vulnerability in Craft CMS allows authenticated control panel users with low privileges to reorder global sets. This alters structure and writes to the project configuration database schema without administrative rights.
Prior to versions 10.9.8 and 11.16.1, Mermaid is vulnerable to prototype pollution via its deep-merge utility function assignWithDepth. This helper is invoked by public configuration-setting interfaces, specifically mermaid.initialize, mermaidAPI.setConfig, and mermaidAPI.updateSiteConfig. Because assignWithDepth recursively merges developer-provided properties into Mermaid's internal configuration state without proper sanitization, an attacker who can control or influence the configuration payload can corrupt the global Object.prototype. This vulnerability can lead to security bypasses, cross-site scripting (XSS), or execution flow modifications in applications using vulnerable Mermaid integrations.
A high-severity path traversal vulnerability exists in Traefik's Kubernetes Ingress NGINX provider. The flaw resides in the RewriteTarget middleware, which is auto-generated when an Ingress resource specifies the `nginx.ingress.kubernetes.io/rewrite-target` annotation. This allows remote, unauthenticated attackers to bypass route-level authentication and access restricted downstream endpoints by exploiting a parser differential.