diff --git a/docs/content/en/open_source/upgrading/2.57.md b/docs/content/en/open_source/upgrading/2.57.md
index aeb39538930..2a31552c08d 100644
--- a/docs/content/en/open_source/upgrading/2.57.md
+++ b/docs/content/en/open_source/upgrading/2.57.md
@@ -2,6 +2,13 @@
title: 'Upgrading to DefectDojo Version 2.57.x'
toc_hide: true
weight: -20260302
-description: No special instructions.
+description: HTML sanitization library replaced (bleach → nh3).
---
-There are no special instructions for upgrading to 2.57.x. Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.57.0) for the contents of the release.
+Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.57.0) for the contents of the release.
+
+## HTML sanitization: bleach replaced by nh3
+
+The `bleach` library has been replaced by [`nh3`](https://nh3.readthedocs.io/) for HTML sanitization. This is a drop-in replacement in most cases, but there are two minor behavioral changes to be aware of:
+
+- **`style` attributes are no longer allowed.** `bleach` supported CSS property-level filtering (e.g. allowing only `color` or `font-weight`). `nh3` has no equivalent, so `style` attributes are stripped entirely to avoid allowing arbitrary CSS injection. Content that previously relied on inline styles (e.g. colored text in the login banner, background-color on markdown images) will lose that styling.
+- **Disallowed tags are stripped rather than escaped.** Previously, a tag like `"
engagement.source_code_management_uri = ""
- self.assertEqual('<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>', finding.get_file_path_with_link())
+ self.assertEqual(
+ '<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>',
+ finding.get_file_path_with_link())
def test_get_references_with_links_no_references(self):
finding = Finding()
@@ -348,32 +354,32 @@ def test_get_references_with_links_no_links(self):
def test_get_references_with_links_simple_url(self):
finding = Finding()
finding.references = "URL: https://www.example.com"
- self.assertEqual('URL: https://www.example.com', finding.get_references_with_links())
+ self.assertEqual('URL: https://www.example.com', finding.get_references_with_links())
def test_get_references_with_links_url_with_port(self):
finding = Finding()
finding.references = "http://www.example.com:8080"
- self.assertEqual('http://www.example.com:8080', finding.get_references_with_links())
+ self.assertEqual('http://www.example.com:8080', finding.get_references_with_links())
def test_get_references_with_links_url_with_path(self):
finding = Finding()
finding.references = "URL https://www.example.com/path/part2 behind URL"
- self.assertEqual('URL https://www.example.com/path/part2 behind URL', finding.get_references_with_links())
+ self.assertEqual('URL https://www.example.com/path/part2 behind URL', finding.get_references_with_links())
def test_get_references_with_links_complicated_url_with_parameter(self):
finding = Finding()
finding.references = "URL:https://www.example.com/path?param1=abc&_param2=xyz"
- self.assertEqual('URL:https://www.example.com/path?param1=abc&_param2=xyz', finding.get_references_with_links())
+ self.assertEqual('URL:https://www.example.com/path?param1=abc&_param2=xyz', finding.get_references_with_links())
def test_get_references_with_links_two_urls(self):
finding = Finding()
finding.references = "URL1: https://www.example.com URL2: https://info.example.com"
- self.assertEqual('URL1: https://www.example.com URL2: https://info.example.com', finding.get_references_with_links())
+ self.assertEqual('URL1: https://www.example.com URL2: https://info.example.com', finding.get_references_with_links())
def test_get_references_with_links_linebreak(self):
finding = Finding()
finding.references = "https://www.example.com\nhttps://info.example.com"
- self.assertEqual('https://www.example.com\nhttps://info.example.com', finding.get_references_with_links())
+ self.assertEqual('https://www.example.com\nhttps://info.example.com', finding.get_references_with_links())
def test_get_references_with_links_markdown(self):
finding = Finding()
diff --git a/unittests/test_os_message.py b/unittests/test_os_message.py
index 3b43b1e3de5..813e49e0c85 100644
--- a/unittests/test_os_message.py
+++ b/unittests/test_os_message.py
@@ -43,7 +43,7 @@ def test_headline_inline_markdown(self):
text = "# Read the **release notes** at [link](https://example.com)\n"
result = os_message.parse_os_message(text)
self.assertIn("release notes", result["message"])
- self.assertIn('link', result["message"])
+ self.assertIn('link', result["message"])
self.assertIsNone(result["expanded_html"])
def test_headline_strips_disallowed_html(self):
diff --git a/unittests/tools/test_api_sonarqube_importer.py b/unittests/tools/test_api_sonarqube_importer.py
index 8dd3b9eafa0..4f3b83a5eb4 100644
--- a/unittests/tools/test_api_sonarqube_importer.py
+++ b/unittests/tools/test_api_sonarqube_importer.py
@@ -351,8 +351,8 @@ def test_get_rule_details_sanitizes_markdown_html(self):
)
self.assertIn("