Aug 31, 2026·6 min read·17 visits
Authenticated users lacking file creation or modification privileges can bypass authorization during the file ingestion phase. This allows them to write temporary chunk files to the server's cache directory that persist for 24 hours, presenting a low-complexity vector for disk exhaustion and Denial of Service.
A missing authorization vulnerability (CWE-862) in Kirby CMS (versions 5.0.0 through 5.5.1) allows low-privileged authenticated users with Panel access to write temporary chunk files to disk, leading to potential Denial of Service via storage exhaustion.
Kirby CMS is a file-based content management system that exposes a REST API for content management. Under standard deployment conditions, users with administrative or editor roles interact with this API to manage content assets. To optimize performance and facilitate the ingestion of large media files, the Kirby REST API implements a chunked file upload handler.
The vulnerability designated as CVE-2026-71415 represents a missing authorization flaw (CWE-862) situated inside this chunked upload processing flow. Authenticated users with basic administrative Panel access (the access.panel permission) can access this handler, regardless of whether they possess the privileges required to create, modify, or replace files on the targeted model.
Because the file upload handler does not validate if the caller is authorized to write files to the destination page or user profile during the initial ingestion phase, unauthorized disk writes are permitted. This exposes an attack vector where low-privileged accounts can stream and store large file fragments in the server's local cache directory.
The root cause of this vulnerability lies in the deferred execution of authorization checks inside the Kirby REST API upload controller. When a chunked file transfer is initiated via an HTTP POST request, the route handlers delegate processing to Kirby\Api\Upload::process(), which subsequently invokes Upload::processChunk(). This function generates a temporary file path on disk and writes the incoming data stream directly into the site/cache/.uploads directory.
In vulnerable versions of Kirby CMS, the API endpoints do not evaluate permission rules against the authenticated user prior to creating or appending data to these temporary files. The authorization callback, which verifies the user's files.create, files.replace, or user/users.update permissions, is executed only within the finalization closure. This closure is run exclusively after all chunks have been received and are ready to be merged.
The following diagram outlines the vulnerability flow where validation is deferred:
An attacker can exploit this delayed authorization by initiating multiple chunked transfers but intentionally leaving them incomplete. Because Kirby CMS retains unfinished chunk files on disk for up to 24 hours to support resumed connections, the temporary files remain on the filesystem, bypassing the validation checks that would otherwise reject the request.
The fix commit 37e206f3ed40ad3fab2e47e055ccb19e9c207dab addresses the missing authorization by implementing preflight authorization checks and state-locking metadata files.
In the patched version, the REST API endpoints define a preflight closure that is executed before any file data is accepted or written to the disk. The following snippet illustrates how the preflight callback validates permissions on the file model before processing:
// config/api/routes/files.php
return $this->upload(
callback: function ($source, $filename) use ($parent) {
return $parent->createFile([ ... ], move: true);
},
preflight: function (string $filename, string|null $template) use ($parent) {
$file = new File([
'parent' => $parent,
'filename' => $filename,
'template' => $template
]);
if ($file->permissions()->can('create') !== true) {
throw new PermissionException(
message: 'The file cannot be created'
);
}
}
);Additionally, the patch implements state-locking metadata sidecar files (a .json file containing template and size parameters) written during the first chunk processing (offset === 0). During subsequent chunk uploads, the application calls validateChunk() to verify that the template and total file length match the locked state:
// src/Api/Upload.php -> validateChunk()
$descriptor = F::exists($meta) === true
? json_decode(F::read($meta), true)
: null;
if (
is_array($descriptor) === false ||
($descriptor['template'] ?? null) !== $template ||
($descriptor['total'] ?? null) !== $total
) {
throw new InvalidArgumentException(
message: 'The file template and upload length must not change between chunks'
);
}These additions prevent template smuggling attacks where an attacker might attempt to alter metadata between chunk uploads to bypass blueprint validation logic.
To exploit this vulnerability, an attacker must first obtain a valid session on the Kirby CMS target with access.panel enabled. No other specialized privileges are required. The attacker then targets the file creation API route (such as /api/pages/<page-slug>/files) and initiates a chunked transfer request.
The attacker constructs an HTTP POST request containing standard chunked upload headers, including Upload-Length set to a large value (e.g., 5,000,000 bytes), Upload-Offset set to 0, and a unique tracking identifier in the Upload-Id header. The body of this request contains the initial chunk data.
By systematically initiating numerous parallel chunk uploads across multiple endpoints and intentionally abandoning them prior to the finalization block, the attacker causes the server to accumulate orphan chunk data inside /site/cache/.uploads. Because these files persist for 24 hours before cleanup routines execute, the host filesystem can be driven to storage exhaustion.
The overall security impact of this vulnerability is high, carrying a CVSS v4.0 base score of 7.1. While the vulnerability does not directly expose sensitive data or allow arbitrary code execution, disk space exhaustion on the host server results in a localized Denial of Service.
In typical PHP environments, complete storage exhaustion prevents the operating system from writing session data, system log entries, and application caches. On Kirby CMS installations, this state can halt database operations, interrupt standard site functions, and block administrators from saving configuration changes.
The impact is limited to the Availability metric (VA:H), as there is no path to compromise the integrity or confidentiality of existing system files through this mechanism. Unfinished files remain trapped within the local cache folder and are not moved into publicly accessible directories.
To eliminate the vulnerability, administrators must upgrade their Kirby CMS installations to version 5.5.2 or higher. The updated versions incorporate the preflight authorization checks and state verification protocols required to reject unauthorized chunked upload requests.
If immediate patching is not feasible, administrators can implement temporary filesystem monitoring. Regularly executing an audit on the site/cache/.uploads directory can help detect abnormal patterns, such as thousands of incomplete chunk files originating from a single user session.
Additionally, implementing disk storage quotas for the PHP process owner or partitioning the cache folder onto a dedicated volume will prevent cache directory growth from consuming critical system disk partitions.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
kirby getkirby | >= 5.0.0, < 5.5.2 | 5.5.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-862 (Missing Authorization) |
| Attack Vector | Network |
| CVSS v4.0 Score | 7.1 (High) |
| Exploit Status | None |
| KEV Status | Not Listed |
| Ransomware Use | No |
The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
An authentication bypass vulnerability in pyLoad allows unauthenticated remote attackers to gain administrative API access. The vulnerability is caused by a logical flaw in the API key cache validation lookup, where authentication states are cached using only the public key identifier, skipping cryptographic token verification on cache hits.
An authorization bypass vulnerability in Strawberry GraphQL between versions 0.217.0 and 0.326.1 occurs when a synchronous permission handler returns an awaitable object (such as an unawaited coroutine). Due to Python's truthiness rules, the unawaited coroutine is evaluated as True, leading to an immediate bypass of security policies.
An uncontrolled resource consumption vulnerability in Strawberry GraphQL allows unauthenticated remote attackers to trigger a Denial of Service on persistent WebSocket connections using the legacy graphql-ws protocol. When the server enforces max_subscriptions_per_connection, naturally terminating subscriptions are not cleared from memory registries, leading to exhaustion of connection slots.
A high-severity type-confusion vulnerability exists in NearForm fast-jwt prior to version 6.3.0. The vulnerability allows attackers to bypass crucial claim validation steps (such as expiration, issuer, audience, and subject validations) by presenting a validly signed JSON Web Token structured as a JSON array instead of a JSON object. This occurs because the library's decoder fails to reject JSON arrays during type evaluation.
NearForm fast-jwt prior to version 6.3.0 is vulnerable to an input validation flaw where configuring verifier properties (such as clockTolerance, clockTimestamp, and cacheTTL) with non-finite values like Infinity or NaN allows attackers to bypass temporal claim validations, including expiration (exp) and activation (nbf) boundaries. This validation bypass can result in unauthorized session persistence and cache poisoning.
A critical cryptographic vulnerability in fast-jwt versions 6.2.x prior to 6.3.0 allows unauthenticated remote attackers to execute an asymmetric-to-symmetric algorithm confusion attack due to incomplete validation of leading non-whitespace prefixes.