Feb 12, 2026·6 min read·26 visits
Authenticated users with basic Control Panel access can view restricted assets (PDFs, SVGs, Thumbnails) by bypassing permission checks on specific controller routes. Patch involves adding missing authorization gates.
A granular access control failure in Statamic CMS allows authenticated Control Panel users to bypass container-specific permissions. By directly accessing asset controllers for PDFs, SVGs, and thumbnails, low-privilege users can view and download files from restricted containers (like 'Private' or 'HR') that they are explicitly denied access to in the UI.
Statamic is the darling of the flat-file CMS world. It relies heavily on Laravel, which usually implies a robust security architecture. Most organizations set up their Control Panel (CP) like a fortress: you need a login, you need a role, and you need specific permissions to touch the sensitive stuff. You might have a 'Marketing' role that can edit the blog, and an 'HR' role that handles employee contracts.
The assumption is simple: if the Marketing intern tries to open the 'Executive Bonuses' folder, the system should slap their hand away. And if they use the UI, it does. The folder doesn't even show up in the sidebar. Out of sight, out of mind, right?
Wrong. CVE-2026-25633 is a classic case of "Security by UI Obscurity." While the frontend politely hides the links to sensitive assets, the backend controllers responsible for rendering previews (PDFs, SVGs, thumbnails) were completely agnostic to your permissions. They didn't care who you were, as long as you had a badge to get into the building. It’s like guarding the front door of a bank but leaving the vault wide open for anyone who just walks past the teller.
The root cause here is a failure to apply granular Authorization (AuthZ) at the controller level. In Laravel applications, you typically have middleware that acts as a broad filter. Statamic uses cp.access to ensure that the user is logged in and allowed to access the Control Panel. This is the first line of defense.
However, once inside, specific actions require specific checks. If you want to view a file in the private container, the code should check $user->can('view', $asset). In the affected versions of Statamic, several controllers—specifically PdfController, SvgController, and ThumbnailController—skipped this step entirely.
These controllers take a Base64-encoded ID, decode it to find the file path on the disk, and stream the content back to the browser. They assumed that if you knew the ID, you probably had the right to see it. This implies a trust model where knowledge of an identifier equals authorization to access the resource, which is a dangerous fallacy when those identifiers are predictable.
Let's look at the smoking gun in Statamic\Http\Controllers\CP\Assets\PdfController. The vulnerable code simply took the asset ID and served it up. It relied entirely on the surrounding middleware for protection, which was insufficient for granular control.
Vulnerable Code (Simplified):
public function show($encoded_id)
{
$asset = Asset::find(base64_decode($encoded_id));
if (! $asset) {
abort(404);
}
// Look ma, no hands! (No authorization check)
return $asset->download();
}The Fix (Commit 5a6f472):
The fix is elegantly simple but highlights exactly what was missing. The developers added a standard Laravel authorization gate using $this->authorize(). This forces the application to run the specific policy associated with viewing that asset.
public function show($encoded_id)
{
$asset = Asset::find(base64_decode($encoded_id));
if (! $asset) {
abort(404);
}
// The Guard Dog is now awake
$this->authorize('view', $asset);
return $asset->download();
}This same pattern was applied across the SvgController and ThumbnailController. If the user's role does not explicitly grant permission to the container holding the asset, the application now throws a 403 Forbidden.
To exploit this, an attacker needs two things: a valid low-privilege account with CP access, and the ability to guess asset IDs. In Statamic, asset IDs are constructed using the format container_handle::path/to/file.ext.
Let's assume there is a restricted container named financials containing a file q1_report.pdf. The ID is financials::q1_report.pdf. An attacker simply needs to Base64 encode this string to generate the payload.
Attack Chain:
private or docs. They guess a filename, perhaps standardizing on dates or common terms.private::hr/layoff_list.pdfcHJpdmF0ZTo6aHIvbGF5b2ZmX2xpc3QucGRmhttps://target.com/cp/pdfs/cHJpdmF0ZTo6aHIvbGF5b2ZmX2xpc3QucGRm.Because the PdfController didn't check if the user had access to the private container, the browser renders the PDF immediately. This works for SVGs and generic thumbnails as well, allowing an attacker to map out the file structure of restricted directories visually.
While this vulnerability scores a relatively modest 4.3 on the CVSS scale, the real-world impact depends entirely on what you are hiding. For a blog, this is a nothing-burger. For a corporate intranet or a client portal, it's a disaster.
This is a pure Confidentiality breach. It allows lateral movement of data access within the application. A user trusted to edit the "Lunch Menu" should not be able to read the "Merger Acquisition Strategy".
Furthermore, because this affects endpoints often used for automated preview generation, an attacker could potentially script an enumeration attack, iterating through likely filenames and checking for 200 OK responses vs 404s, effectively scraping the entire restricted filesystem.
The remediation is straightforward: update Statamic. The patch was released in versions 5.73.6 and 6.2.5. These versions enforce the view permission check on all asset retrieval endpoints.
If you cannot update immediately, you are in a tight spot because this is a logic flaw in the core code, not a configuration issue. You could theoretically implement a WAF rule to block access to /cp/pdfs/* and /cp/thumbnails/* for users who shouldn't have access, but mapping that logic at the edge is complex and error-prone.
Post-Patch Action: Check your access logs for GET requests to /cp/pdfs/ or /cp/svgs/ originating from IP addresses or user accounts that should not have had access to those specific resources. A sudden spike in 403s after patching might indicate someone was relying on this access, or an automated scraper getting blocked.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Statamic CMS Statamic | < 5.73.6 | 5.73.6 |
Statamic CMS Statamic | >= 6.0.0-alpha.1, < 6.2.5 | 6.2.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862 |
| Attack Vector | Network |
| CVSS | 4.3 (Medium) |
| Authentication | Required (Low Privilege) |
| Impact | Confidentiality Loss |
| Exploit Status | Functional PoC |
The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
An issue was discovered in the tokio-postgres library for Rust prior to version 0.7.18. A trust assumption mismatch between the PostgreSQL protocol messages sent by a server and how they are parsed and indexed by the client-side library allows a rogue or compromised database server to trigger a Denial of Service (DoS) crash via an unhandled out-of-bounds slice indexing panic.
CVE-2026-14669 is a critical heap-based buffer overflow vulnerability in PostgreSQL's date/time formatting function to_char(timestamptz). The flaw arises from unsafe copying of user-controlled timezone abbreviations into a fixed-size internal buffer. An authenticated database user can trigger this issue by setting a long POSIX timezone abbreviation containing custom formatting, allowing them to overwrite adjacent heap structures and hijack execution control to achieve remote code execution (RCE) with the privileges of the 'postgres' operating system user.
An unauthenticated remote denial of service vulnerability exists in the Unleash feature management platform. By submitting a crafted JSON payload containing deeply nested structures to an OpenAPI-validated endpoint, an attacker can trigger uncontrolled recursion within the error formatting module. This leads to a call-stack exhaustion (RangeError: Maximum call stack size exceeded) inside the Node.js runtime, causing the service to crash immediately without recovery.
CVE-2026-63004 is a server-side request forgery (SSRF) vulnerability in the Unleash feature management platform. Authenticated administrators with CREATE_ADDON or UPDATE_ADDON privileges can exploit this vulnerability to initiate requests to loopback addresses, private networks, and cloud metadata endpoints, potentially leading to information disclosure and credential extraction.
Prior to version 8.0.3, Unleash's Markdown event formatter directly mutated the global template-escaping function of the shared mustache Node.js module, resulting in a process-wide security degradation where HTML/Markdown escaping was permanently disabled for the application lifetime.
A critical SQL injection vulnerability exists in the GeoTools open-source Java library. This vulnerability is situated within the post-processing phase of OGC Filter conversion inside the PostGIS DataStore module. Specifically, the `jsonArrayContains` function does not validate or sanitize its arguments before constructing PostgreSQL SQL/JSON path evaluation queries. An unauthenticated remote attacker can exploit this weakness by submitting crafted filters via standard OGC services like WFS or WMS to execute arbitrary SQL commands on the underlying database system.