From 7eb48de8876e452d1d30b41a2717fb33649611ed Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Mon, 16 Mar 2026 10:13:31 -0400 Subject: [PATCH 1/3] fix: xss bypass in allowed protocol test using unicode invisible characters This fixes sanitize_uri_values where it wouldn't correctly filter uris with disallowed protocols if the scheme had a unicode invisible character in it. Now the code strips all non-ASCII characters from the uri before parsing and testing the scheme. GHSA-8rfp-98v4-mmr6 --- CHANGES | 18 +++++++++++++++++- bleach/sanitizer.py | 11 ++++++----- tests/test_clean.py | 16 ++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 2cae93d3..154832dc 100644 --- a/CHANGES +++ b/CHANGES @@ -10,7 +10,23 @@ Version 6.4.0 (TBD) **Security fixes** -None +* Fix bug 2023812 / GHSA-8rfp-98v4-mmr6. + + Fix XSS issue with sanitize_uri_value where disallowed schemes with + Unicode invisible characters wouldn't be rejected. + + For example:: + + import bleach + payload1 = 'Click' + result1 = bleach.clean(payload1) + print(repr(result1)) + + outputs:: + + 'Click' + + See the advisory for details. **Bug fixes** diff --git a/bleach/sanitizer.py b/bleach/sanitizer.py index 01282835..dd8f6e65 100644 --- a/bleach/sanitizer.py +++ b/bleach/sanitizer.py @@ -488,14 +488,15 @@ def sanitize_uri_value(self, value, allowed_protocols): # Convert all character entities in the value normalized_uri = html5lib_shim.convert_entities(value) - # Nix backtick, space characters, and control characters + # Strip backtick, whitespace, and control characters normalized_uri = re.sub(r"[`\000-\040\177-\240\s]+", "", normalized_uri) - # Remove REPLACEMENT characters - normalized_uri = normalized_uri.replace("\ufffd", "") + # Strip non-ASCII characters so that urlparse can parse the url into + # components correctly. This drops invisible and whitespace unicode + # characters among other things. + normalized_uri = re.sub(r"[^\x00-\x7f]", "", normalized_uri) - # Lowercase it--this breaks the value, but makes it easier to match - # against + # Lowercase value to make matching easier normalized_uri = normalized_uri.lower() try: diff --git a/tests/test_clean.py b/tests/test_clean.py index 4021ef14..622ba0f8 100644 --- a/tests/test_clean.py +++ b/tests/test_clean.py @@ -618,6 +618,22 @@ def test_attributes_list(): # Disallowed protocols with sneaky character entities ('alert', {}, "alert"), ('alert', {}, "alert"), + # Disallowed protocols with Unicode characters injected + ( + 'alert', + {"protocols": ALLOWED_PROTOCOLS}, + "alert", + ), + ( + 'alert', + {"protocols": ALLOWED_PROTOCOLS}, + "alert", + ), + ( + 'alert', + {"protocols": ALLOWED_PROTOCOLS}, + "alert", + ), # Checking the uri should change it at all ( 'foo', From 06a04bda34e5bafc9854e7be3a43c5b1ac6d264e Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Fri, 5 Jun 2026 07:52:48 -0400 Subject: [PATCH 2/3] fix: uri-sanitization in formaction attributes GHSA-gj48-438w-jh9v --- CHANGES | 6 ++++++ bleach/_vendor/03_html5lib_formaction.patch | 12 ++++++++++++ bleach/_vendor/html5lib/filters/sanitizer.py | 1 + bleach/_vendor/vendor_install.sh | 1 + tests/test_clean.py | 15 +++++++++++++++ 5 files changed, 35 insertions(+) create mode 100644 bleach/_vendor/03_html5lib_formaction.patch diff --git a/CHANGES b/CHANGES index 154832dc..f79360f8 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,12 @@ Version 6.4.0 (TBD) See the advisory for details. +* Fix GHSA-gj48-438w-jh9v. + + Fix issue where URI sanitization wasn't happening in formaction attributes. + + See the advisory for details. + **Bug fixes** * Add support for pypy 3.11. (#764) diff --git a/bleach/_vendor/03_html5lib_formaction.patch b/bleach/_vendor/03_html5lib_formaction.patch new file mode 100644 index 00000000..0b8b050e --- /dev/null +++ b/bleach/_vendor/03_html5lib_formaction.patch @@ -0,0 +1,12 @@ +diff --git bleach/_vendor/html5lib/filters/sanitizer.py b/bleach/_vendor/html5lib/filters/sanitizer.py +index a37c9d8..dd5a6a6 100644 +--- bleach/_vendor/html5lib/filters/sanitizer.py ++++ bleach/_vendor/html5lib/filters/sanitizer.py +@@ -534,6 +534,7 @@ attr_val_is_uri = frozenset(( + (None, 'dynsrc'), + (None, 'lowsrc'), + (None, 'ping'), ++ (None, 'formaction'), + (namespaces['xlink'], 'href'), + (namespaces['xml'], 'base'), + )) diff --git a/bleach/_vendor/html5lib/filters/sanitizer.py b/bleach/_vendor/html5lib/filters/sanitizer.py index a37c9d8d..dd5a6a60 100644 --- a/bleach/_vendor/html5lib/filters/sanitizer.py +++ b/bleach/_vendor/html5lib/filters/sanitizer.py @@ -534,6 +534,7 @@ (None, 'dynsrc'), (None, 'lowsrc'), (None, 'ping'), + (None, 'formaction'), (namespaces['xlink'], 'href'), (namespaces['xml'], 'base'), )) diff --git a/bleach/_vendor/vendor_install.sh b/bleach/_vendor/vendor_install.sh index df888345..875bb78d 100755 --- a/bleach/_vendor/vendor_install.sh +++ b/bleach/_vendor/vendor_install.sh @@ -13,6 +13,7 @@ pip install --no-binary all --no-compile --no-deps -r "${BLEACH_VENDOR_DIR}/vend # Apply patches (cd "${DEST}" && patch -p2 < 01_html5lib_six.patch) (cd "${DEST}" && patch -p2 < 02_html5lib_wbr.patch) +(cd "${DEST}" && patch -p2 < 03_html5lib_formaction.patch) # install Python 3.6.14 urllib.urlparse for #536 curl --proto '=https' --tlsv1.2 -o "${DEST}/parse.py" https://raw.githubusercontent.com/python/cpython/v3.6.14/Lib/urllib/parse.py diff --git a/tests/test_clean.py b/tests/test_clean.py index 622ba0f8..02ccc67e 100644 --- a/tests/test_clean.py +++ b/tests/test_clean.py @@ -427,6 +427,21 @@ def test_poster_attribute(): assert clean(ok, tags=tags, attributes=attrs) == ok +def test_formaction_attribute(): + """formaction attributes should not allow javascript (GHSA-gj48-438w-jh9v).""" + tags = {"button", "input"} + attrs = {"button": ["formaction"], "input": ["formaction", "type"]} + + test = '' + assert clean(test, tags=tags, attributes=attrs) == "" + + test = '' + assert clean(test, tags=tags, attributes=attrs) == '' + + ok = '' + assert clean(ok, tags=tags, attributes=attrs) == ok + + def test_attributes_callable(): """Verify attributes can take a callable""" From c530b8bf305f078cf9448ef2cf3c45cd986c1fcd Mon Sep 17 00:00:00 2001 From: Will Kahn-Greene Date: Fri, 5 Jun 2026 08:26:45 -0400 Subject: [PATCH 3/3] chore: bleach 6.4.0 and final release This is the last release of Bleach. There will be no future releases including for security fixes. Thank you all for using and contributing to Bleach! --- CHANGES | 4 ++++ CONTRIBUTING.rst | 23 +++++------------------ CONTRIBUTORS | 13 ++++++++----- README.rst | 14 +++----------- SECURITY.md | 21 +++------------------ bleach/__init__.py | 4 ++-- setup.py | 2 +- 7 files changed, 26 insertions(+), 55 deletions(-) diff --git a/CHANGES b/CHANGES index f79360f8..a55bab07 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,10 @@ Bleach changes Version 6.4.0 (TBD) ------------------- +**NOTE: 2026-06-05: Bleach is no longer maintained. There will be no future +releases including for security issues.** +See issue: ``__ + **Backwards incompatible changes** * Dropped support for pypy 3.10. (#764) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 00521dee..250b8286 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -1,19 +1,6 @@ -Reporting Bugs -============== +Status +====== -For regular bugs, please report them `in our issue tracker -`_. - - -Reporting security bugs ------------------------ - -If you believe that you've found a security vulnerability, please `file a secure -bug report in our bug tracker -`_ -or send an email to *security AT mozilla DOT org*. - -For more information on security-related bug disclosure and the PGP key to use -for sending encrypted mail or to verify responses received from that address, -please read our wiki page at -``_. +**NOTE: 2026-06-05: Bleach is no longer maintained. There will be no future +releases including for security issues.** +See issue: https://github.com/mozilla/bleach/issues/698 diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 487375a0..c46b50a4 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,18 +1,21 @@ +**NOTE: 2026-06-05: Bleach is no longer maintained. There will be no future +releases including for security issues.** +See issue: https://github.com/mozilla/bleach/issues/698 + Bleach was originally written and maintained by James Socol and various contributors within and without the Mozilla Corporation and Foundation. -It is currently maintained by Will Kahn-Greene, Greg Guthe, and Jon Dufresne. - Maintainers: -- Will Kahn-Greene -- Greg Guthe -- Jon Dufresne +None Maintainer emeritus: - Jannis Leidel - James Socol +- Greg Guthe +- Jon Dufresne +- Will Kahn-Greene Contributors: diff --git a/README.rst b/README.rst index 6adaefae..1219acf0 100644 --- a/README.rst +++ b/README.rst @@ -2,17 +2,9 @@ Bleach ====== -.. image:: https://github.com/mozilla/bleach/workflows/Test/badge.svg - :target: https://github.com/mozilla/bleach/actions?query=workflow%3ATest - -.. image:: https://github.com/mozilla/bleach/workflows/Lint/badge.svg - :target: https://github.com/mozilla/bleach/actions?query=workflow%3ALint - -.. image:: https://badge.fury.io/py/bleach.svg - :target: http://badge.fury.io/py/bleach - -**NOTE: 2023-01-23: Bleach is deprecated.** See issue: -``__ +**NOTE: 2026-06-05: Bleach is no longer maintained. There will be no future +releases including for security issues.** +See issue: ``__ Bleach is an allowed-list-based HTML sanitizing library that escapes or strips markup and attributes. diff --git a/SECURITY.md b/SECURITY.md index 48d87a5f..529b62d9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,20 +1,5 @@ # Security Policy -## Supported Versions - -Use this section to tell people about which versions of your project are -currently being supported with security updates. - -| Version | Supported | -| ------- | ------------------ | -| 4.1.x | :white_check_mark: | -| < 4 | :x: | - -## Reporting a Vulnerability - -If you believe that you've found a security vulnerability, please [file a secure -bug report in our bug tracker](https://bugzilla.mozilla.org/enter_bug.cgi?assigned_to=nobody%40mozilla.org&product=Webtools&component=Bleach-security&groups=webtools-security) or send an email to *security AT mozilla DOT org*. - -For more information on security-related bug disclosure and the PGP key to use -for sending encrypted mail or to verify responses received from that address, -please read our wiki page at https://www.mozilla.org/en-US/security/#For_Developers +**NOTE: 2026-06-05: Bleach is no longer maintained. There will be no future +releases including for security issues.** +See issue: https://github.com/mozilla/bleach/issues/698 diff --git a/bleach/__init__.py b/bleach/__init__.py index b056e84d..9802e64b 100644 --- a/bleach/__init__.py +++ b/bleach/__init__.py @@ -11,9 +11,9 @@ # yyyymmdd -__releasedate__ = "20251027" +__releasedate__ = "20260605" # x.y.z or x.y.z.dev0 -- semver -__version__ = "6.3.0" +__version__ = "6.4.0" __all__ = ["clean", "linkify"] diff --git a/setup.py b/setup.py index b6a1dcf8..a9d6c83b 100755 --- a/setup.py +++ b/setup.py @@ -55,7 +55,7 @@ def get_version(): install_requires=INSTALL_REQUIRES, extras_require=EXTRAS_REQUIRE, classifiers=[ - "Development Status :: 5 - Production/Stable", + "Development Status :: 7 - Inactive", "Environment :: Web Environment", "Intended Audience :: Developers", "Operating System :: OS Independent",