` AssetsController::actionDeleteFolder()` somente requer a permissão `deleteAssets: ` para a pasta de alvo. Ele nunca aplica `deletePeerAssets: `, mesmo que `Assets::deleteFoldersByIds()` exclua em cascatas para cada pasta descendente e cada ativo dentro, independentemente de quem os tenha carregado. Um usuário de baixa prioridade que recebeu direitos de gestão de pastas em um volume compartilhado pode, portanto, destruir os ativos carregados por outros usuários (ativos de par), evitando a verificação de permissão de pares por ativo que o endpoint `actionDeleteAsset` do irmão se aplica corretamente. Esta é a mesma classe de erros que foi corrigida em `actionMoveFolder` como **GHSA- 3 w 32 - 23 wj- rxg 3 ** (commitiu ` 05 c 2042 `, abr 23 2026 ); a correção adicionada `requireVolumePermissionByFolder('deletePeerAssets',...)` e `savePeerAssets' verifica ao objetivo de movimento, mas não se propagou para o objetivo de delete- folder. `src/ controllers/ AssetsController.php: 552 - 569 `. ``` php ação da função públicaDeleteFolder(): Resposta { $this->requireAcceptsJson(); $folderId = $this->request->getRequiredBodyParam('folderId');.
$assets = Craft::$app->getAssets(); $folder = $assets->getFolderById($folderId). if (!$folder) { lançar novo BadRequestHttpException('A pasta não pode ser encontrada'); } // Verifique se é possível excluir objetos no volume alvo. $this->requireVolumePermissionByFolder('deleteAssets', $folder); // deleteFoldersByIds($folderId); devolver $this->asSucesso(); } ```. `requireVolumePermissionByFolder()` (`src/ controllers/ AssetsControllerTrait.php: 75 - 88 `) só resolve para uma chamada simples `requirePermission('deleteAssets: '). O ajudante equivalente a pares (`requirePeerVolumePermissionByAsset`) nunca é invocado porque não existe ajudante de pares de nível de pasta que itera o conteúdo da pasta.
`Assets::deleteFoldersByIds()` (`src/ services/Assets.php: 311 - 349 ") em seguida, enumera a pasta + cada pasta descendente, consulta cada ativo sob esses IDs, e chama "Craft::$app->getElements()->deleteElement($asset, true)` diretamente: ```php $assetQuery = Asset::find()->folderId($allFolderIds); $elementService = Craft::$app->getElements(). foreach (Db::each($assetQuery) como $asset) { $asset-> manter oFileOnDelete =!$deleteDir; $elementService->deleteElement($asset, true); } ```.
Isto evita o `Asset::canDelete()` (`src/elements/Asset.php: 1515 - 1536 `). ````php public function canDelete(User $user): bool { se ($this->isFolder) { devolver falso; } se (pai::canDelete($user)) { devolve verdadeiro; } $volume = $this->getVolume(); se (Assuntos:::estempUploadFs($volume->getFs())) { devolve verdadeiro; } if ($this->uploaderId! == $user->id) { devolve $user->can("deletePeerAssets:$volume->uid"); // can("deleteAssets:$volume->uid"); } ````. Compare com `actionDeleteAsset` (`src/controllers/AssetsController.php: 579 - 613 `), que faz corretamente:.
```php $this->requireVolumePermissionByAsset('deleteAssets', $asset'); $this->requirePeerVolumePermissionByAsset('deletePeerAssets', $asset'); ```. A correção que aterrou em ` 05 c 2042 ` para `actionMoveFolder` (`src/ controllers/ AssetsController.php: 733 - 765 `) adicionaram as verificações `salvePeerAssets` e `deletePeerAssets` `requireVolumePermissionByFolder` para refletir o padrão por ativo, mas o mesmo endurecimento não foi aplicado a `actionDeleteFolder` ou `actionRenameFolder` (que também chama `deleteFoldersByIds` indiretamente através de lógicas posteriores). A assimetria entre os dois endpoints demonstra a verificação faltante.
- Integridade / disponibilidade de ativos de outros usuários em qualquer volume onde o atacante tenha `deleteAssets' mas não `deletePeerAssets`: o atacante pode remover permanentemente arquivos de propriedade de pares (e sua estrutura de pasta pai) no sistema de arquivos subjacente, sem recuperação através da interface de usuário do Craft. - O modelo de permissão do Craft distingue explicitamente "delete your own assets" (`deleteAssets`) de "delete os assets de outros usuários" (`deletePeerAssets`) precisamente para que os administradores possam conceder o primeiro sem o último em volumes compartilhados — esta constatação torna essa distinção inexequível para qualquer usuário dado direitos de pasta-delete. - Nenhuma divulgação de informações ou execução de código remoto; o impacto está vinculado ao conteúdo do volume afetado. - Não requer qualquer ação de ativos de outros usuários. configuração não predefinida: o objetivo afetado está ativado por padrão e só requer que um administrador tenha dividido "deleteAssets" de "deletePeerAssets" (o modelo documentado de permissão suportado). Registro de aconselhamento: GHSA- 7 h 62 - 6 v 23 - v 8 FM. Identificadores relacionados: CVE- 2026 - 50284.
Tempo: GitHub Advisory Database publicou este registro em 2026 - 07 - 02 T 18: 49: 04.000 Z e lista a sua última modificação como 2026 - 07 - 02 T 18: 49: 04.000 Z. Severidade: ALTAMENTE. Dados de pontuação publicados: CVSS_V 4: CVSS: 4.0 /AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:L/África do Sul:N.
Software afetado e informações de versão: Packagist package craftcms/cms — ECOSISTEM: introduzido 5.0.0 - RC 1, corrigido 5.9.22. Pacote packagist craftcms/cms — ECOSISTEM: introduzido 4.0.0 - RC 1, corrigido 4.17.15. Classificação e evidência: identificadores de fraqueza CWE- 862. O registro contém 4 suporte de referências nestes tipos: WEB, AVISO, EMBALAGAMENTO.