Skip to content

Commit e7403c5

Browse files
chore(deps): replace bleach with nh3 for HTML sanitization
bleach is deprecated and archived. nh3 is its Rust-backed successor, actively maintained and significantly faster.
1 parent 20cdba0 commit e7403c5

4 files changed

Lines changed: 23 additions & 37 deletions

File tree

dojo/templatetags/display_tags.py

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
from itertools import chain
99
from pathlib import Path
1010

11-
import bleach
1211
import dateutil.relativedelta
1312
import markdown
14-
from bleach.css_sanitizer import CSSSanitizer
13+
import nh3
1514
from django import template
1615
from django.conf import settings
1716
from django.contrib.auth.models import User
@@ -51,17 +50,21 @@
5150
}
5251

5352
markdown_attrs = {
54-
"*": ["id"],
55-
"img": ["src", "alt", "title", "width", "height", "style"],
56-
"a": ["href", "alt", "target", "title"],
57-
"span": ["class"], # used for code highlighting
58-
"pre": ["class"], # used for code highlighting
59-
"div": ["class"], # used for code highlighting
53+
"*": {"id"},
54+
"img": {"src", "alt", "title", "width", "height"},
55+
"a": {"href", "alt", "target", "title"},
56+
"span": {"class"}, # used for code highlighting
57+
"pre": {"class"}, # used for code highlighting
58+
"div": {"class"}, # used for code highlighting
6059
}
6160

62-
markdown_styles = [
63-
"background-color",
64-
]
61+
# nh3 base allowlist (equivalent to bleach.ALLOWED_TAGS / bleach.ALLOWED_ATTRIBUTES)
62+
_NH3_ALLOWED_TAGS = {"a", "abbr", "acronym", "b", "blockquote", "code", "em", "i", "li", "ol", "strong", "ul"}
63+
_NH3_ALLOWED_ATTRIBUTES = {
64+
"a": {"href", "title", "target"},
65+
"abbr": {"title"},
66+
"acronym": {"title"},
67+
}
6568

6669
finding_related_action_classes_dict = {
6770
"reset_finding_duplicate_status": "fa-solid fa-eraser",
@@ -92,21 +95,13 @@ def markdown_render(value):
9295
"markdown.extensions.fenced_code",
9396
"markdown.extensions.toc",
9497
"markdown.extensions.tables"])
95-
return mark_safe(bleach.clean(markdown_text, tags=markdown_tags, attributes=markdown_attrs, css_sanitizer=CSSSanitizer(allowed_css_properties=markdown_styles)))
98+
return mark_safe(nh3.clean(markdown_text, tags=markdown_tags, attributes=markdown_attrs))
9699
return None
97100

98101

99102
@register.filter
100103
def bleach_with_a_tags(message):
101-
# Create a copy of ALLOWED_ATTRIBUTES to avoid mutating the global
102-
allowed_attributes = {
103-
**bleach.ALLOWED_ATTRIBUTES,
104-
"a": [*bleach.ALLOWED_ATTRIBUTES.get("a", []), "style", "target"],
105-
}
106-
return mark_safe(bleach.clean(
107-
message,
108-
attributes=allowed_attributes,
109-
css_sanitizer=CSSSanitizer(allowed_css_properties=["color", "font-weight"])))
104+
return mark_safe(nh3.clean(message, tags=_NH3_ALLOWED_TAGS, attributes=_NH3_ALLOWED_ATTRIBUTES))
110105

111106

112107
def text_shortener(value, length):

dojo/templatetags/get_banner.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import bleach
2-
from bleach.css_sanitizer import CSSSanitizer
1+
import nh3
32
from django import template
43
from django.utils.safestring import mark_safe
54

65
from dojo.models import BannerConf
6+
from dojo.templatetags.display_tags import _NH3_ALLOWED_ATTRIBUTES, _NH3_ALLOWED_TAGS
77

88
register = template.Library()
99

@@ -15,16 +15,8 @@ def get_banner_conf(attribute):
1515
value = getattr(banner_config, attribute, None)
1616
if value:
1717
if attribute == "banner_message":
18-
# only admin can edit login banner, so we allow html, but still bleach it
19-
# Create a copy of ALLOWED_ATTRIBUTES to avoid mutating the global
20-
allowed_attributes = {
21-
**bleach.ALLOWED_ATTRIBUTES,
22-
"a": [*bleach.ALLOWED_ATTRIBUTES.get("a", []), "style", "target"],
23-
}
24-
return mark_safe(bleach.clean(
25-
value,
26-
attributes=allowed_attributes,
27-
css_sanitizer=CSSSanitizer(allowed_css_properties=["color", "font-weight"])))
18+
# only admin can edit login banner, so we allow html, but still sanitize it
19+
return mark_safe(nh3.clean(value, tags=_NH3_ALLOWED_TAGS, attributes=_NH3_ALLOWED_ATTRIBUTES))
2820
return value
2921
except Exception:
3022
return False

dojo/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
from math import pi, sqrt
1818
from pathlib import Path
1919

20-
import bleach
2120
import crum
2221
import cvss
22+
import nh3
2323
import redis as redis_lib
2424
import vobject
2525
from amqp.exceptions import ChannelError
@@ -1539,7 +1539,7 @@ def create_bleached_link(url, title):
15391539
link += '">'
15401540
link += title
15411541
link += "</a>"
1542-
return bleach.clean(link, tags={"a"}, attributes={"a": ["href", "target", "title"]})
1542+
return nh3.clean(link, tags={"a"}, attributes={"a": {"href", "target", "title"}})
15431543

15441544

15451545
def get_object_or_none(klass, *args, **kwargs):

requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# requirements.txt for DefectDojo using Python 3.x
2-
bleach==6.3.0
3-
bleach[css]
2+
nh3
43
celery[sqs]==5.6.3
54
# pycurl and boto3 are included via celery[sqs] for Celery Broker AWS (SQS) support
65
defusedxml==0.7.1

0 commit comments

Comments
 (0)