Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.
Open advisories
10 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.
The CMS page cache key ignores the request headers that plugins declare via getvarycacheon(). The header is added to the response Vary header, but the CMS's own cache key does not incorporate the header values, so the first visitor's variant is served to all subsequent visitors regardless of their header values. Details pagecachekey (in cms/cache/page.py) keys only on cache prefix, site, language, path and timezone. setpagecache collects the plugin-declared vary headers and calls patchvaryheaders(response, ...) (affecting only the emitted Vary header), but stores and retrieves the cached page under the header-agnostic key. getpagecache therefore returns whichever variant was cached first. Impact - Information disclosure: when a plugin varies its output on a request header (e.g. Country-Code), the variant rendered for the first anonymous visitor is served to everyone until the entry expires, leaking request-specific content across users. - Cache poisoning: an unauthenticated…
Recommended action: Upgrade to 5.0.8 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The moveplugin admin endpoint does not prevent a plugin from being reparented under itself or one of its own descendants. Doing so creates a cycle in the plugin tree, after which the recursive descendant/ancestor SQL queries loop without terminating, stalling the request worker. Details moveplugin (in cms/admin/placeholderadmin.py) accepts a pluginparent POST parameter and, for an in-placeholder move, sets the plugin's parent to the target without any cycle/ancestor check. If the target parent is a descendant of the moved plugin, the resulting parentid graph contains a cycle. Descendant and ancestor traversal is implemented with WITH RECURSIVE CTEs (getdescendantscte / getancestorscte in cms/models/pluginmodel.py) that have no cycle clause or depth limit. On a cyclic tree these recurse indefinitely (PostgreSQL/SQLite) or error at the recursion limit (MySQL). getdescendants() is invoked while building the move response and on subsequent operations on the affected subtree.…
Recommended action: Upgrade to 5.0.8 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The django-cms frontend-editing structure endpoint did not perform an object-level authorization check for non-PageContent objects. Any authenticated, active staff user could request the structure endpoint for a frontend-editable object (a model using PlaceholderRelationField) and read its placeholder/plugin structure, even without permission to change that object and without the cms.usestructure permission that the toolbar UI requires before offering structure mode. PageContent objects were already protected (a page-view check added in GHSA/PR #8644); this advisory covers the remaining non-PageContent branch of the same view. Severity The issue is staff-gated and read-only, disclosing CMS structure metadata (placeholder slot names, plugin tree, plugin identifiers/labels, object existence) rather than write access or arbitrary field data. Affected versions - django-cms = 4.0.0, <= 5.0.x and 5.1.0a1 (the vulnerable non-PageContent branch was introduced with the…
Recommended action: Upgrade to 5.0.9 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact The only authorization gate on the duplicate flow is PageAdmin.hasaddpermission, which checks usercanaddpage(user, site) / usercanaddsubpage(...) — i.e. “may this user create a page at all”. Nothing checks the user’s relationship to the page being copied: - cms/admin/forms.py — DuplicatePageForm.source = ModelChoiceField(queryset=Page.objects.all(), widget=HiddenInput()) spans every page in the database, on every site. - cms/admin/forms.py — AddPageForm.init returns early when the source widget is hidden, so the queryset is never narrowed to the user’s site/subtree. - cms/admin/forms.py — AddPageForm.clean() validates only URL uniqueness; source is never validated against the user. - cms/admin/pageadmin.py — duplicate() seeds source from the URL only on GET; on POST the value comes entirely from the request body. - cms/admin/forms.py — AddPageForm.save() → fromsource() performs source.copy(..., permissions=False) and copies every placeholder and all plugins of source into a…
Recommended action: Upgrade to 5.0.9 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
When plugin rendering fails in edit mode, django CMS renders a cms-rendering-exception block so editors can see that a placeholder could not be rendered. Older code built that block's heading by interpolating the exception message, placeholder/source strings, and the failing plugin's short description directly into an HTML string, then returned the placeholder output as safe markup. If an editor could store HTML in data used by a plugin's getshortdescription() (or in other values interpolated into the exception message), and that plugin later raised during edit-mode rendering, the payload was parsed as HTML in the staff user's browser. This is a stored XSS condition in the CMS editing context. Impact The vulnerable path is only reached when placeholder rendering catches a plugin rendering exception: renderexception() constructs a message from values that can include stored content: - value - the exception message. - placeholder - the placeholder string representation. -…
Recommended action: Upgrade to 5.0.9 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The structure-board endpoint (renderobjectstructure) renders a page's plugin structure without verifying that the requesting user is allowed to view the page. The edit and preview endpoints enforce this via renderpage(), but the structure endpoint does not, allowing a low-privileged staff user to read the plugin structure of a view-restricted page. Details renderobjectstructure (in cms/views.py) loads the PageContent object and renders cms/toolbar/structure.html directly. Unlike renderobjectendpoint (used by edit/preview), which renders through renderpagecontent → renderpage and calls usercanviewpage(request.user, page) (returning 404 when the user may not view the page), the structure endpoint performs no page-level authorization. The rendered structure board includes each plugin's getshortdescription() (e.g. link names/URLs, text snippets), so the content of a restricted page is disclosed, not just its shape. Impact A staff user (any account with isstaff=True) who lacks…
Recommended action: Upgrade to 5.0.8 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
The clipboard copy paths of the copyplugins admin endpoint validate only the target (the user's own clipboard) and skip source-side authorization. A staff user can copy plugins out of a placeholder they have no permission on into their clipboard, then read the (secret) content. Details In cms/admin/placeholderadmin.py, copyplugintoclipboard and copyplaceholdertoclipboard check hascopypluginspermission, which only evaluates request.toolbar.clipboard.hasaddpluginspermission(...) — the clipboard belongs to the requesting user, and checksource is likewise applied only to the clipboard. The source placeholder identified by the attacker-supplied sourceplaceholderid / sourcepluginid is never authorization-checked. (The placeholder-to-placeholder copy path, hascopyfromplaceholderpermission, correctly checks both sides.) Impact A staff user holding the global add permission for a plugin type, but with no access to a given placeholder/page, can copy that placeholder's plugins…
Recommended action: Upgrade to 5.0.8 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Improper Neutralization of Input During Web Page Generation (XSS or 'Cross-site Scripting') vulnerability in django CMS Association django-cms allows Cross-Site Scripting (XSS).This issue affects django-cms: 3.11.7, 3.11.8, 4.1.2, 4.1.3.
Recommended action: Upgrade to 4.1.4 or 3.11.9 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Cross-site request forgery (CSRF) vulnerability in django CMS before 3.0.14, 3.1.x before 3.1.1 allows remote attackers to manipulate privileged users into performing unknown actions.
Recommended action: Upgrade to 3.1.1 or 3.0.14 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Django CMS 3.7.3 does not validate the plugintype parameter while generating error messages for an invalid plugin type, resulting in a Cross Site Scripting (XSS) vulnerability. The vulnerability allows an attacker to execute arbitrary JavaScript code in the web browser of the affected user.
Recommended action: Upgrade to 3.7.4, 3.6.1, 3.5.4 or 3.4.7 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.