Potential Observable Timing Discrepancy in Wagtail
Description
In Wagtail before versions 2.7.3 and 2.8.2, a potential timing attack exists on pages or documents that have been protected with a shared password through Wagtail's "Privacy" controls. This password check is performed through a character-by-character string comparison, and so an attacker who is able to measure the time taken by this check to a high degree of accuracy could potentially use timing differences to gain knowledge of the password. This is understood to be feasible on a local network, but not on the public internet.
Privacy settings that restrict access to pages/documents on a per-user or per-group basis (as opposed to a shared password) are unaffected by this vulnerability.
This has been patched in 2.7.3, 2.8.2, 2.9.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
wagtailPyPI | < 2.7.3 | 2.7.3 |
wagtailPyPI | >= 2.8rc1, < 2.8.2 | 2.8.2 |
wagtailPyPI | >= 2.9rc1, < 2.9 | 2.9 |
Affected products
1Patches
4b76ab57ee859Release note for CVE-2020-11037 in 2.9
2 files changed · +9 −0
CHANGELOG.txt+1 −0 modified@@ -28,6 +28,7 @@ Changelog * Add caching of image renditions (Tom Dyson, Tim Kamanin) * Add documentation for reporting security issues and internationalisation (Matt Westcott) * Fields on a custom image model can now be defined as required `blank=False` (Matt Westcott) + * Fix: CVE-2020-11037 - avoid potential timing attack on password-protected private pages (Thibaud Colas) * Fix: Added ARIA alert role to live search forms in the admin (Casper Timmers) * Fix: Reorder login form elements to match expected tab order (Kjartan Sverrisson) * Fix: Re-add 'Close Explorer' button on mobile viewports (Sævar Öfjörð Magnússon)
docs/releases/2.9.rst+8 −0 modified@@ -16,6 +16,14 @@ Report data exports Data from reports, form submissions and ModelAdmin can now be exported to both XLSX and CSV format. For ModelAdmin, this is enabled by specifying a ``list_export`` attribute on the ModelAdmin class. This feature was developed by Jacob Topp-Mugglestone and sponsored by `The Motley Fool <https://www.fool.com/>`_. +CVE-2020-11037: Potential timing attack on password-protected private pages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This release addresses a potential timing attack on pages or documents that have been protected with a shared password through Wagtail's "Privacy" controls. This password check is performed through a character-by-character string comparison, and so an attacker who is able to measure the time taken by this check to a high degree of accuracy could potentially use timing differences to gain knowledge of the password. (This is `understood to be feasible on a local network, but not on the public internet <https://groups.google.com/d/msg/django-developers/iAaq0pvHXuA/fpUuwjK3i2wJ>`_.) + +Many thanks to Thibaud Colas for reporting this issue. + + Other features ~~~~~~~~~~~~~~
3c030490ed57Use constant_time_compare for view restriction password checks
1 file changed · +2 −1
wagtail/core/forms.py+2 −1 modified@@ -1,4 +1,5 @@ from django import forms +from django.utils.crypto import constant_time_compare from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy @@ -13,7 +14,7 @@ def __init__(self, *args, **kwargs): def clean_password(self): data = self.cleaned_data['password'] - if data != self.restriction.password: + if not constant_time_compare(data, self.restriction.password): raise forms.ValidationError(_("The password you have entered is not correct. Please try again.")) return data
bac3cd0a26b0Use constant_time_compare for view restriction password checks
1 file changed · +2 −1
wagtail/core/forms.py+2 −1 modified@@ -1,4 +1,5 @@ from django import forms +from django.utils.crypto import constant_time_compare from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy @@ -13,7 +14,7 @@ def __init__(self, *args, **kwargs): def clean_password(self): data = self.cleaned_data['password'] - if data != self.restriction.password: + if not constant_time_compare(data, self.restriction.password): raise forms.ValidationError(_("The password you have entered is not correct. Please try again.")) return data
ba9d424bd1caUse constant_time_compare for view restriction password checks
1 file changed · +2 −1
wagtail/core/forms.py+2 −1 modified@@ -1,4 +1,5 @@ from django import forms +from django.utils.crypto import constant_time_compare from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy @@ -13,7 +14,7 @@ def __init__(self, *args, **kwargs): def clean_password(self): data = self.cleaned_data['password'] - if data != self.restriction.password: + if not constant_time_compare(data, self.restriction.password): raise forms.ValidationError(_("The password you have entered is not correct. Please try again.")) return data
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
8- github.com/advisories/GHSA-jjjr-3jcw-f8v6ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-11037ghsaADVISORY
- github.com/pypa/advisory-database/tree/main/vulns/wagtail/PYSEC-2020-153.yamlghsaWEB
- github.com/wagtail/wagtail/commit/3c030490ed575bb9cd01dfb3a890477dcaeb2edfghsax_refsource_MISCWEB
- github.com/wagtail/wagtail/commit/b76ab57ee859732b9cf9287d380493ab24061090ghsax_refsource_MISCWEB
- github.com/wagtail/wagtail/commit/ba9d424bd1ca5ce1910d3de74f5cc07214fbfb11ghsax_refsource_MISCWEB
- github.com/wagtail/wagtail/commit/bac3cd0a26b023e595cf2959aae7da15bb5e4340ghsax_refsource_MISCWEB
- github.com/wagtail/wagtail/security/advisories/GHSA-jjjr-3jcw-f8v6ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.