Moderate severityNVD Advisory· Published Mar 24, 2026· Updated Mar 25, 2026
Craft CMS: Authorization bypass in "entries/move-to-section" allows control panel user to move entries without section permissions
CVE-2026-33162
Description
Craft CMS is a content management system (CMS). From version 5.3.0 to before version 5.9.14, an authenticated control panel user with only accessCp can move entries across sections via POST /actions/entries/move-to-section, even when they do not have saveEntries:{sectionUid} permission for either source or destination section. This issue has been patched in version 5.9.14.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
craftcms/cmsPackagist | >= 5.3.0, < 5.9.14 | 5.9.14 |
Affected products
1Patches
13c1ab1c4445dFixed GHSA-f582-6gf6-gx4g
3 files changed · +24 −7
CHANGELOG.md+2 −0 modified@@ -3,7 +3,9 @@ ## Unreleased - The `PDO::MYSQL_ATTR_MULTI_STATEMENTS` attribute is no longer set by default for database connections. ([#18474](https://github.com/craftcms/cms/issues/18474)) +- Added `craft\elements\Entry::canMove()`. - Fixed a bug where element selector modals weren’t showing any results if they were limited to sources that only exist for a different site than the active one. ([#18478](https://github.com/craftcms/cms/issues/18478)) +- Fixed a [moderate-severity](https://github.com/craftcms/cms/security/policy#severity--remediation) authorization bypass vulnerability. (GHSA-f582-6gf6-gx4g) ## 5.9.13 - 2026-02-24
src/controllers/EntriesController.php+15 −4 modified@@ -463,26 +463,37 @@ public function actionMoveToSection(): Response $this->requireCpRequest(); $sectionId = $this->request->getRequiredParam('sectionId'); + $entryIds = $this->request->getRequiredParam('entryIds'); + if (empty($entryIds)) { + throw new BadRequestHttpException('entryIds cannot be empty.'); + } + $section = Craft::$app->getEntries()->getSectionById($sectionId); if (!$section) { throw new BadRequestHttpException('Cannot find the section to move the entries to.'); } - $entryIds = $this->request->getRequiredParam('entryIds'); - if (empty($entryIds)) { - throw new BadRequestHttpException('entryIds cannot be empty.'); - } + $this->requirePermission("viewEntries:$section->uid"); + + /** @var Entry[] $entries */ $entries = Entry::find() ->id($entryIds) ->status(null) ->drafts(null) ->site('*') ->unique() ->all(); + if (empty($entries)) { throw new BadRequestHttpException('Cannot find the entries to move to the new section.'); } + foreach ($entries as $entry) { + if (!$entry->canMove()) { + throw new ForbiddenHttpException('User is not authorized to perform this action.'); + } + } + $errors = []; foreach ($entries as $entry) { try {
src/elements/Entry.php+7 −3 modified@@ -2497,15 +2497,19 @@ protected function htmlAttributes(string $context): array return [ 'data' => [ 'entry-type-id' => $this->getType()->id, - 'movable' => $this->_canMove(), + 'movable' => $this->canMove(), ], ]; } /** - * Returns whether the given user is authorized to move this entry. + * Returns whether the given user is authorized to move this entry to a different section. + * + * @param User|null $user + * @return bool + * @since 5.9.14 */ - private function _canMove(?User $user = null): bool + public function canMove(?User $user = null): bool { if (!$user) { $user = Craft::$app->getUser()->getIdentity();
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-f582-6gf6-gx4gghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-33162ghsaADVISORY
- github.com/craftcms/cms/commit/3c1ab1c4445dd9237855a66e6a06ecf3591a718eghsax_refsource_MISCWEB
- github.com/craftcms/cms/releases/tag/5.9.14ghsax_refsource_MISCWEB
- github.com/craftcms/cms/security/advisories/GHSA-f582-6gf6-gx4gghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.