CVE-2026-54623: django CMS: Plugin move endpoint allows cyclic reparenting (DoS)
django CMS is an easy-to-use and developer-friendly enterprise content management system powered by Django. Prior to 5.0.8, the moveplugin endpoint in cms/admin/placeholderadmin.py accepts an attacker-controlled pluginparent value without rejecting a plugin’s own identifier or a descendant identifier. A staff user with plugin-change permission under CMSPERMISSION can create a parentid cycle in the plugin tree. The getdescendantscte and getancestorscte queries in cms/models/pluginmodel.py have no cycle guard, so getdescendants() and later rendering, copy, or delete operations can recurse indefinitely or reach a database recursion limit, corrupting the tree and consuming request workers. This issue is fixed in versions 5.0.8.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
django CMSto a version that resolves this vulnerability.Fixed in 5.0.8
Event History
Frequently Asked Questions
Who can exploit this issue?
Exploitation requires a staff user with plugin-change permission when CMS_PERMISSION is enabled. The attacker must be able to submit a request to the plugin move endpoint with a controlled plugin_parent value.
What impact can a successful attack have?
An attacker can create a cycle in the plugin tree, corrupting its parent-child structure. Later rendering, copy, or delete operations may recurse indefinitely or hit database recursion limits, consuming request workers and causing denial of service.
Which versions are affected and what is the fix?
Versions prior to 5.0.8 are affected. Upgrade django CMS to version 5.0.8, which rejects a plugin's own identifier or a descendant identifier as its parent during plugin moves.
How can I determine whether my instance may already be affected?
Inspect plugin tree relationships for parent_id cycles, particularly where a plugin is its own parent or where a plugin's parent chain leads back to that plugin. Operational signs include failures or recursion-limit errors during plugin rendering, copying, deleting, or descendant/ancestor lookup operations.