Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-50283

CVE-2026-50283: Craft CMS Auth Bypass Vulnerability

CVE-2026-50283 is an authorization bypass flaw in Craft CMS that allows authenticated users to delete assets without proper permissions. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-50283 Overview

Craft CMS contains an authorization flaw in AssetsController::actionReplaceFile that allows authenticated users to delete assets in volumes where they lack delete permission. The issue affects versions 5.0.0-RC1 through 5.9.20 and 4.0.0-RC1 through 4.17.13. When a request supplies both assetId and sourceAssetId, the controller resolves the permission check against the target asset only, skipping enforcement on the source asset. Craft then copies the source file into the target and deletes the source asset, resulting in broken content references and data loss. The vulnerability is tracked as [CWE-639] Authorization Bypass Through User-Controlled Key. Fixes are available in versions 4.17.14 and 5.9.21.

Critical Impact

An authenticated user with replace permission in one volume can delete arbitrary assets in another volume without holding delete permission, causing content loss.

Affected Products

  • Craft CMS versions 5.0.0-RC1 through 5.9.20
  • Craft CMS versions 4.0.0-RC1 through 4.17.13
  • Fixed in Craft CMS 4.17.14 and 5.9.21

Discovery Timeline

  • 2026-07-01 - CVE-2026-50283 published to NVD
  • 2026-07-02 - Last updated in NVD database

Technical Details for CVE-2026-50283

Vulnerability Analysis

The flaw resides in AssetsController::actionReplaceFile(), which supports replacing a target asset file using another existing asset as the source. The action loads two objects from user-supplied identifiers: assetId becomes $assetToReplace and sourceAssetId becomes $sourceAsset. Before the patch, permission enforcement used the expression ($assetToReplace ?: $sourceAsset), which returns the first truthy value.

When both identifiers are supplied, the expression resolves to $assetToReplace, so Craft checks replaceFiles and replacePeerFiles only against the target volume. The source asset volume is never validated. Craft then copies the source file into the target and deletes the original source asset, though no deleteAssets permission check is performed against the source volume.

Root Cause

The root cause is missing authorization on a user-controlled object reference [CWE-639]. Using the null coalescing behavior on two independently controlled asset IDs collapses two distinct permission scopes into a single check. The deletion side effect on the source asset has no matching authorization gate.

Attack Vector

An authenticated user with replaceFiles permission in any volume can send a crafted request to the asset replace endpoint containing both assetId (in their own volume) and sourceAssetId (referencing an asset in a restricted volume). Craft deletes the referenced source asset without validating delete permission on the source volume.

php
// Patch applied in src/controllers/AssetsController.php
// Before (vulnerable):
// $this->requireVolumePermissionByAsset('replaceFiles', $assetToReplace ?: $sourceAsset);
// $this->requirePeerVolumePermissionByAsset('replacePeerFiles', $assetToReplace ?: $sourceAsset);

// After (fixed): both assets are independently checked
if ($assetToReplace) {
    $this->requireVolumePermissionByAsset('replaceFiles', $assetToReplace);
    $this->requirePeerVolumePermissionByAsset('replacePeerFiles', $assetToReplace);
}
if ($sourceAsset) {
    $this->requireVolumePermissionByAsset('replaceFiles', $sourceAsset);
    $this->requirePeerVolumePermissionByAsset('replacePeerFiles', $sourceAsset);
}

// Handle the Element Action
if ($assetToReplace !== null && $uploadedFile) {

Source: GitHub Commit 2c2579c

Detection Methods for CVE-2026-50283

Indicators of Compromise

  • POST requests to the assets replace-file endpoint containing both assetId and sourceAssetId parameters referencing distinct volumes.
  • Craft CMS audit logs showing asset deletions initiated by users who lack deleteAssets permission on the source volume.
  • Unexpected broken asset references in entries, categories, or Matrix blocks following asset replace actions.

Detection Strategies

  • Enable and review Craft CMS activity and asset audit logs, focusing on replace-file actions where the acting user has no delete rights in the affected volume.
  • Inspect web server logs for HTTP requests to /actions/assets/replace-file that include both assetId and sourceAssetId fields in the POST body.
  • Correlate asset deletion events with the volumes and permission sets of the acting user identity.

Monitoring Recommendations

  • Alert on repeated replace-file requests originating from low-privilege authenticated accounts.
  • Monitor for spikes in asset deletion events across sensitive volumes containing production media.
  • Track drift between the running Craft CMS version and the fixed releases 4.17.14 and 5.9.21.

How to Mitigate CVE-2026-50283

Immediate Actions Required

  • Upgrade Craft CMS to version 4.17.14 or 5.9.21 immediately.
  • Audit recent asset deletions and replace-file activity to identify any unauthorized removals.
  • Review and restrict replaceFiles and replacePeerFiles permissions to trusted user groups only.

Patch Information

Craft CMS resolved the issue in versions 4.17.14 and 5.9.21. The fix, referenced in commit 2c2579c7f1030872423f268d0c8b48377101961d, splits the single conditional permission check into two independent checks that validate replaceFiles and replacePeerFiles permissions against both the target and the source assets. Additional hardening in src/elements/Asset.php tightens the canMoveTo logic to require saveAssets, deleteAssets, savePeerAssets, and deletePeerAssets permissions on the destination volume. See the Craft CMS Security Advisory GHSA-qh45-9g5p-m2v4.

Workarounds

  • Revoke replaceFiles permission from any user group that does not require it until the upgrade is applied.
  • Restrict asset volumes so low-privilege users cannot enumerate sourceAssetId values in other volumes.
  • Place the Craft CMS control panel behind an authenticated reverse proxy or IP allowlist to limit exposure.
bash
# Upgrade Craft CMS via Composer to a patched release
composer require craftcms/cms:^5.9.21 --update-with-dependencies
# or for the 4.x branch
composer require craftcms/cms:^4.17.14 --update-with-dependencies

# Clear caches and run pending migrations
php craft clear-caches/all
php craft migrate/all

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.