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("

Heading

", rule_details) - self.assertIn('safe', rule_details) - self.assertIn("unsafe", rule_details) + self.assertIn('safe', rule_details) + self.assertIn('unsafe', rule_details) self.assertNotIn("References", rule_details) - self.assertIn('OWASP', rule_details) - self.assertIn("unsafe", rule_details) + self.assertIn('OWASP', rule_details) + self.assertIn('unsafe', rule_details) self.assertNotIn("