VYPR
High severityNVD Advisory· Published Apr 3, 2023· Updated Feb 13, 2025

Wagtail vulnerable to stored Cross-site Scripting attack via ModelAdmin views

CVE-2023-28836

Description

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 packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
wagtailPyPI
>= 1.5, < 4.1.44.1.4
wagtailPyPI
>= 4.2, < 4.2.24.2.2

Affected products

1

Patches

4
eefc3381d37b

Release note for CVE-2023-28836 in 4.1.4

https://github.com/wagtail/wagtailMatt WestcottApr 3, 2023via ghsa
2 files changed · +7 0
  • CHANGELOG.txt+1 0 modified
    @@ -293,6 +293,7 @@ Changelog
     4.1.4 (xx.xx.xxxx) - IN DEVELOPMENT
     ~~~~~~~~~~~~~~~~~~
     
    + * Fix: CVE-2023-28836 - Stored XSS attack via ModelAdmin views (Thibaud Colas)
      * Fix: Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
      * Fix: Fix select elements expanding beyond their container when using a long option label (Sage Abdullah)
      * Fix: Fix timezone handling of `TemplateResponse`s for users with a custom timezone (Stefan Hammer, Sage Abdullah)
    
  • docs/releases/4.1.4.md+6 0 modified
    @@ -11,6 +11,12 @@ depth: 1
     
     ## What's new
     
    +### CVE-2023-28836: Stored XSS attack via ModelAdmin views
    +
    +This release addresses a stored cross-site scripting (XSS) vulnerability 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.
    +
    +Many thanks to Thibaud Colas for reporting this issue. For further details, please see [the CVE-2023-28836 security advisory](https://github.com/wagtail/wagtail/security/advisories/GHSA-5286-f2rf-35c2).
    +
     ### Bug fixes
     
     * Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
    
bc84bf981561

Release note for CVE-2023-28836 in 4.2.2

https://github.com/wagtail/wagtailMatt WestcottApr 3, 2023via ghsa
2 files changed · +7 0
  • CHANGELOG.txt+1 0 modified
    @@ -105,6 +105,7 @@ Changelog
     4.2.2 (xx.xx.xxxx) - IN DEVELOPMENT
     ~~~~~~~~~~~~~~~~~~
     
    + * Fix: CVE-2023-28836 - Stored XSS attack via ModelAdmin views (Thibaud Colas)
      * Fix: Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
      * Fix: Fix select elements expanding beyond their container when using a long option label (Sage Abdullah)
      * Fix: Fix timezone handling of `TemplateResponse`s for users with a custom timezone (Stefan Hammer, Sage Abdullah)
    
  • docs/releases/4.2.2.md+6 0 modified
    @@ -11,6 +11,12 @@ depth: 1
     
     ## What's new
     
    +### CVE-2023-28836: Stored XSS attack via ModelAdmin views
    +
    +This release addresses a stored cross-site scripting (XSS) vulnerability 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.
    +
    +Many thanks to Thibaud Colas for reporting this issue. For further details, please see [the CVE-2023-28836 security advisory](https://github.com/wagtail/wagtail/security/advisories/GHSA-5286-f2rf-35c2).
    +
     ### Bug fixes
     
     * Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
    
ff806ab173a5

Change ModelAdmin InspectView to escape any HTML from document titles

https://github.com/wagtail/wagtailThibaud ColasMar 27, 2023via ghsa
2 files changed · +23 9
  • wagtail/contrib/modeladmin/tests/test_simple_modeladmin.py+16 0 modified
    @@ -13,6 +13,8 @@
     from wagtail.admin.admin_url_finder import AdminURLFinder
     from wagtail.admin.panels import FieldPanel, TabbedInterface
     from wagtail.contrib.modeladmin.helpers.search import DjangoORMSearchHandler
    +from wagtail.documents.models import Document
    +from wagtail.documents.tests.utils import get_test_document_file
     from wagtail.images.models import Image
     from wagtail.images.tests.utils import get_test_image_file
     from wagtail.models import Locale, ModelLogEntry, Page
    @@ -591,6 +593,20 @@ def test_book_author_present(self):
             response = self.get_for_book(1)
             self.assertContains(response, "J. R. R. Tolkien", 1)
     
    +    def test_book_extract_document_html_escaping(self):
    +        doc = Document.objects.create(
    +            title="Title with <script>alert('XSS')</script>",
    +            file=get_test_document_file(),
    +        )
    +        book = Book.objects.get(title="The Lord of the Rings")
    +        book.extract_document = doc
    +        book.save()
    +        response = self.get_for_book(1)
    +        self.assertNotContains(response, "Title with <script>alert('XSS')</script>")
    +        self.assertContains(
    +            response, "Title with &lt;script&gt;alert(&#x27;XSS&#x27;)&lt;/script&gt;"
    +        )
    +
         def test_non_existent(self):
             response = self.get_for_book(100)
             self.assertEqual(response.status_code, 404)
    
  • wagtail/contrib/modeladmin/views.py+7 9 modified
    @@ -29,8 +29,8 @@
     from django.utils.decorators import method_decorator
     from django.utils.encoding import force_str
     from django.utils.functional import cached_property
    +from django.utils.html import format_html
     from django.utils.http import urlencode
    -from django.utils.safestring import mark_safe
     from django.utils.text import capfirst
     from django.utils.translation import gettext as _
     from django.utils.translation import gettext_lazy
    @@ -1131,14 +1131,12 @@ def get_document_field_display(self, field_name, field):
             """Render a link to a document"""
             document = getattr(self.instance, field_name)
             if document:
    -            return mark_safe(
    -                '<a href="%s">%s <span class="meta">(%s, %s)</span></a>'
    -                % (
    -                    document.url,
    -                    document.title,
    -                    document.file_extension.upper(),
    -                    filesizeformat(document.file.size),
    -                )
    +            return format_html(
    +                '<a href="{}">{} <span class="meta">({}, {})</span></a>',
    +                document.url,
    +                document.title,
    +                document.file_extension.upper(),
    +                filesizeformat(document.file.size),
                 )
             return self.model_admin.get_empty_value_display(field_name)
     
    
5be2b1ed55fd

Change ChooseParentView to use plain text breadcrumbs for page titles, avoiding stored XSS vector

https://github.com/wagtail/wagtailThibaud ColasMar 27, 2023via ghsa
2 files changed · +16 2
  • wagtail/contrib/modeladmin/forms.py+1 2 modified
    @@ -1,5 +1,4 @@
     from django import forms
    -from django.utils.safestring import mark_safe
     from django.utils.translation import gettext as _
     
     from wagtail.models import Page
    @@ -12,7 +11,7 @@ def label_from_instance(self, obj):
                 obj.get_ancestors(inclusive=True).exclude(depth=1).specific(defer=True)
             ):
                 bits.append(ancestor.get_admin_display_title())
    -        return mark_safe('<span class="icon icon-arrow-right"></span>'.join(bits))
    +        return " | ".join(bits)
     
     
     class ParentChooserForm(forms.Form):
    
  • wagtail/contrib/modeladmin/tests/test_page_modeladmin.py+15 0 modified
    @@ -286,6 +286,21 @@ def test_back_to_listing(self):
             """
             self.assertContains(response, expected, html=True)
     
    +    def test_page_title_html_escaping(self):
    +        homepage = Page.objects.get(url_path="/home/")
    +        business_index = BusinessIndex(
    +            title="Title with <script>alert('XSS')</script>",
    +        )
    +        homepage.add_child(instance=business_index)
    +
    +        response = self.client.get("/admin/tests/businesschild/choose_parent/")
    +
    +        self.assertEqual(response.status_code, 200)
    +        self.assertNotContains(response, "Title with <script>alert('XSS')</script>")
    +        self.assertContains(
    +            response, "Title with &lt;script&gt;alert(&#x27;XSS&#x27;)&lt;/script&gt;"
    +        )
    +
     
     class TestChooseParentViewForNonSuperuser(TestCase, WagtailTestUtils):
         fixtures = ["test_specific.json"]
    

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

12

News mentions

0

No linked articles in our index yet.