CVE-2023-28836: Wagtail vulnerable to stored Cross-site Scripting attack via ModelAdmin views
Impact
A stored cross-site scripting (XSS) vulnerability exists on ModelAdmin views within the Wagtail admin interface. A user with a limited-permission editor account for the Wagtail admin could potentially craft pages and documents that, when viewed by a user with higher privileges, could perform actions with that user's credentials. The vulnerability is not exploitable by an ordinary site visitor without access to the Wagtail admin, and only affects sites with ModelAdmin enabled.
- For page, the vulnerability is in the "Choose a parent page" ModelAdmin view (ChooseParentView), available when managing pages via ModelAdmin. - For documents, the vulnerability is in the ModelAdmin Inspect view (InspectView) when displaying document fields.
Patches
Patched versions have been released as Wagtail 4.1.4 (for the LTS 4.1 branch) and Wagtail 4.2.2 (for the current 4.2 branch).
Workarounds
Site owners who are unable to upgrade to the new versions can disable or override the corresponding functionality.
ChooseParentView
For ChooseParentView:
- Disable ModelAdmin for all page models. - Or provide a custom view via chooseparentviewclass, with the custom view overriding the getform method.
One of those steps need to be applied for every ModelAdmin class hooked into Wagtail where the model is a Wagtail Page or sub-class. Here is an example of implementing the custom ChooseParentView with patched HTML escaping:
python from django import forms from django.utils.translation import gettext as from wagtail.contrib.modeladmin.views import ChooseParentView from wagtail.contrib.modeladmin.forms import ParentChooserForm
class PatchedPageChoiceField(forms.ModelChoiceField): """PageChoiceField with plain-text breadcrumbs to patch stored XSS.""" def labelfrominstance(self, obj): bits = [] for ancestor in ( obj.getancestors(inclusive=True).exclude(depth=1).specific(defer=True) ): bits.append(ancestor.getadmindisplaytitle()) return ' | '.join(bits)
class PatchedParentChooserForm(ParentChooserForm): """ParentChooserForm with custom parentpage to patch stored XSS.""" parentpage = PatchedPageChoiceField( label=("Parent page"), required=True, emptylabel=None, queryset=Page.objects.none(), widget=forms.RadioSelect(), )
class PatchedChooseParentView(ChooseParentView): """ChooseParentView with custom getform patch stored XSS.""" def getform(self, request): parents = self.permissionhelper.getvalidparentpages(request.user) return PatchedParentChooserForm(parents, request.POST or None)
InspectView
For InspectView:
- Remove inspectviewenabled=True or set it to False to disable the view. - Or use inspectviewfields or inspectviewfieldsexclude to prevent displaying document fields in the views. - Or provide a custom view via inspectviewclass, with the custom view overriding the getdocumentfielddisplay method.
One of those steps need to be applied for every ModelAdmin class hooked into Wagtail where inspectviewenabled=True. Here is an example of implementing the custom InspectView with patched HTML escaping:
python from django.template.defaultfilters import filesizeformat from django.utils.html import formathtml from wagtail.contrib.modeladmin.views import InspectView
class PatchedInspectView(InspectView): """InspectView with override to patch stored XSS vulnerability.""" def getdocumentfielddisplay(self, fieldname, field): """Render a link to a document""" document = getattr(self.instance, fieldname) if document: return formathtml( '<a href="{}">{} <span class="meta">({}, {})</span></a>', document.url, document.title, document.fileextension.upper(), filesizeformat(document.file.size), ) return self.modeladmin.getemptyvaluedisplay(fieldname)
Other sources
Wagtail is an open source content management system built on Django. Starting in version 1.5 and prior to versions 4.1.4 and 4.2.2, a stored cross-site scripting (XSS) vulnerability exists on ModelAdmin views within the Wagtail admin interface. A user with a limited-permission editor account for the Wagtail admin could potentially craft pages and documents that, when viewed by a user with higher privileges, could perform actions with that user's credentials. The vulnerability is not exploitable by an ordinary site visitor without access to the Wagtail admin, and only affects sites with ModelAdmin enabled. For page, the vulnerability is in the "Choose a parent page" ModelAdmin view (ChooseParentView), available when managing pages via ModelAdmin. For documents, the vulnerability is in the ModelAdmin Inspect view (InspectView) when displaying document fields. Patched versions have been released as Wagtail 4.1.4 and Wagtail 4.2.2. Site owners who are unable to upgrade to the new versions can disable or override the corresponding functionality.
Affected Software
Remediation
Event History
Frequently Asked Questions
What is CVE-2023-28836?
CVE-2023-28836 is a stored cross-site scripting (XSS) vulnerability in the ModelAdmin views within the Wagtail admin interface.
What is the severity of CVE-2023-28836?
The severity of CVE-2023-28836 is medium with a CVSS score of 5.4.
Which versions of Wagtail are affected by CVE-2023-28836?
Wagtail versions 1.5 to 4.1.4 and 4.2 to 4.2.2 are affected by CVE-2023-28836.
How can I fix the CVE-2023-28836 vulnerability?
To fix the CVE-2023-28836 vulnerability, you should update your Wagtail installation to versions 4.1.4 or 4.2.2.
Where can I find more information about CVE-2023-28836?
You can find more information about CVE-2023-28836 in the documentation of Wagtail and the associated GitHub commit.