OSV 1.4.0 · github-reviewed · 修改于 2026-07-03 02:48
发布时间
2026-07-03 02:48
GitHub 审查时间
2026-07-03 02:48
NVD 发布时间
2026-07-02 07:16
源文件
advisories/github-reviewed/2026/07/GHSA-qh45-9g5p-m2v4/GHSA-qh45-9g5p-m2v4.json
We have identified an authorization issue in Craft CMS AssetsController::actionReplaceFile that can delete a source asset without source delete permission by supplying both assetId and sourceAssetId.
Craft CMS’s craft\\controllers\\AssetsController::actionReplaceFile() supports replacing a target asset file using another existing asset as the source. The action loads:
$assetToReplace from assetId$sourceAsset from sourceAssetIdIt then enforces replace permissions using ($assetToReplace ?: $sourceAsset). When both IDs are provided, this expression resolves to the target asset so no permission check is performed against the source asset volume.
$this->requireVolumePermissionByAsset('replaceFiles', $assetToReplace ?: $sourceAsset);
$this->requirePeerVolumePermissionByAsset('replacePeerFiles', $assetToReplace ?: $sourceAsset);
src/controllers/AssetsController.php:L433-L434
In the branch where both assets are present, Craft copies the source file into the target and then deletes the source asset. There is no check for deleteAssets:<sourceVolumeUid> or deletePeerAssets:<sourceVolumeUid> for the source asset before deletion.
$assets->replaceAssetFile($assetToReplace, $tempPath, $assetToReplace->getFilename(), $sourceAsset->getMimeType());
Craft::$app->getElements()->deleteElement($sourceAsset);
src/controllers/AssetsController.php:L462-L463
An authenticated user who can replace files in one volume can delete assets in another volume where they do not have delete permission, as long as they can obtain a sourceAssetId. This can lead to unauthorized asset deletion, broken content references, and data loss.