Skip to content

Commit

Permalink
fix: change deprecated bleach to nh3 #202
Browse files Browse the repository at this point in the history
  • Loading branch information
Agus Makmun committed Jul 28, 2023
1 parent 759af77 commit ed8f7b3
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 47 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
### Requirements

* `Django>=3.2`
* `Markdown>=3.0`
* `Markdown<3.4`
* `requests>=2.12.4`
* `bleach`
* [`nh3`](https://pypi.org/project/nh3) _(replacement of `bleach`)_


### Installation
Expand Down
102 changes: 77 additions & 25 deletions martor/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,15 @@
# Markdown urls
MARTOR_UPLOAD_URL = (
# Allows to disable this endpoint
settings.MARTOR_UPLOAD_URL if hasattr(settings, "MARTOR_UPLOAD_URL")
settings.MARTOR_UPLOAD_URL
if hasattr(settings, "MARTOR_UPLOAD_URL")
else "/martor/uploader/"
)

MARTOR_SEARCH_USERS_URL = (
# Allows to disable this endpoint
settings.MARTOR_SEARCH_USERS_URL if hasattr(settings, "MARTOR_SEARCH_USERS_URL")
settings.MARTOR_SEARCH_USERS_URL
if hasattr(settings, "MARTOR_SEARCH_USERS_URL")
else "/martor/search-user/"
)

Expand Down Expand Up @@ -127,7 +129,7 @@
ALLOWED_URL_SCHEMES = getattr(
settings,
"ALLOWED_URL_SCHEMES",
[
{
"file",
"ftp",
"ftps",
Expand All @@ -142,14 +144,14 @@
"tftp",
"vnc",
"xmpp",
],
},
)

# https://gist.github.com/mrmrs/7650266
ALLOWED_HTML_TAGS = getattr(
settings,
"ALLOWED_HTML_TAGS",
[
{
"a",
"abbr",
"b",
Expand Down Expand Up @@ -199,31 +201,81 @@
"tr",
"u",
"ul",
],
},
)

# https://github.com/decal/werdlists/blob/master/html-words/html-attributes-list.txt
ALLOWED_HTML_ATTRIBUTES = getattr(
# https://www.w3schools.com/TAGS/ref_attributes.asp
# https://www.w3schools.com/TAGS/default.asp
# https://www.w3schools.com/TAGS/ref_standardattributes.asp
GLOBAL_HTML_ATTRIBUTES = getattr(
settings,
"ALLOWED_HTML_ATTRIBUTES",
[
"alt",
{
"accesskey",
"class",
"color",
"colspan",
# "data",
"datetime",
"height",
"href",
"contenteditable",
"data-", # https://github.com/messense/nh3/issues/14
"dir",
"draggable",
"hidden",
"id",
"name",
"reversed",
"rowspan",
"scope",
"src",
"lang",
"spellcheck",
"style",
"tabindex",
"title",
"type",
"width",
],
"translate",
},
)

ALLOWED_HTML_ATTRIBUTES = getattr(
settings,
{
"a": GLOBAL_HTML_ATTRIBUTES
| {"href"}, # don't add "rel", it will causing rust error
"abbr": GLOBAL_HTML_ATTRIBUTES,
"blockquote": GLOBAL_HTML_ATTRIBUTES,
"cite": GLOBAL_HTML_ATTRIBUTES,
"code": GLOBAL_HTML_ATTRIBUTES,
"command": GLOBAL_HTML_ATTRIBUTES,
"dd": GLOBAL_HTML_ATTRIBUTES,
"del": GLOBAL_HTML_ATTRIBUTES | {"cite", "datetime"},
"dl": GLOBAL_HTML_ATTRIBUTES,
"dt": GLOBAL_HTML_ATTRIBUTES,
"em": GLOBAL_HTML_ATTRIBUTES,
"fieldset": GLOBAL_HTML_ATTRIBUTES,
"h1": GLOBAL_HTML_ATTRIBUTES,
"h2": GLOBAL_HTML_ATTRIBUTES,
"h3": GLOBAL_HTML_ATTRIBUTES,
"h4": GLOBAL_HTML_ATTRIBUTES,
"h5": GLOBAL_HTML_ATTRIBUTES,
"h6": GLOBAL_HTML_ATTRIBUTES,
"hr": GLOBAL_HTML_ATTRIBUTES,
"iframe": GLOBAL_HTML_ATTRIBUTES,
"img": GLOBAL_HTML_ATTRIBUTES | {"alt", "height", "src", "width"},
"input": GLOBAL_HTML_ATTRIBUTES | {"type", "name", "value"},
"ins": GLOBAL_HTML_ATTRIBUTES | {"cite", "datetime"},
"kbd": GLOBAL_HTML_ATTRIBUTES,
"label": GLOBAL_HTML_ATTRIBUTES | {"for"},
"legend": GLOBAL_HTML_ATTRIBUTES,
"li": GLOBAL_HTML_ATTRIBUTES,
"ol": GLOBAL_HTML_ATTRIBUTES,
"optgroup": GLOBAL_HTML_ATTRIBUTES | {"label"},
"option": GLOBAL_HTML_ATTRIBUTES | {"value"},
"p": GLOBAL_HTML_ATTRIBUTES,
"pre": GLOBAL_HTML_ATTRIBUTES,
"small": GLOBAL_HTML_ATTRIBUTES,
"span": GLOBAL_HTML_ATTRIBUTES,
"strong": GLOBAL_HTML_ATTRIBUTES,
"sub": GLOBAL_HTML_ATTRIBUTES,
"sup": GLOBAL_HTML_ATTRIBUTES,
"table": GLOBAL_HTML_ATTRIBUTES,
"tbody": GLOBAL_HTML_ATTRIBUTES,
"td": GLOBAL_HTML_ATTRIBUTES,
"tfoot": GLOBAL_HTML_ATTRIBUTES,
"th": GLOBAL_HTML_ATTRIBUTES,
"thead": GLOBAL_HTML_ATTRIBUTES,
"tr": GLOBAL_HTML_ATTRIBUTES,
"u": GLOBAL_HTML_ATTRIBUTES,
"ul": GLOBAL_HTML_ATTRIBUTES,
},
)
31 changes: 18 additions & 13 deletions martor/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def test_markdownify(self):
self.assertEqual(response.status_code, 200)
self.assertEqual(
response.content.decode("utf-8"),
'<p><a href="https://python.web.id">python</a></p>',
'<p><a href="https://python.web.id" rel="noopener noreferrer">python</a></p>',
) # noqa: E501

# Image
Expand All @@ -99,21 +99,26 @@ def test_markdownify(self):
'<p><img class="marked-emoji" src="https://github.githubassets.com/images/icons/emoji/heart.png"></p>',
) # noqa: E501

# # Mention
# response = self.client.post(
# "/martor/markdownify/",
# {"content": f"@[{self.user.username}]"},
# )
# self.assertEqual(response.status_code, 200)
# self.assertEqual(
# response.content.decode("utf-8"),
# f'<p><a class="direct-mention-link" href="https://python.web.id/author/{self.user.username}/">{self.user.username}</a></p>',
# )
# Mention
response = self.client.post(
"/martor/markdownify/",
{"content": f"@[{self.user.username}]"},
)
self.assertEqual(response.status_code, 200)
self.assertEqual(
response.content.decode("utf-8"),
(
f'<p><a class="direct-mention-link" href="https://python.web.id/author/{self.user.username}/" '
f'rel="noopener noreferrer">@{self.user.username}</a></p>'
),
)

def test_markdownify_xss_handled(self):
xss_payload_1 = "[aaaa](javascript:alert(1))"
response_1 = markdownify(xss_payload_1)
self.assertEqual(response_1, '<p><a href=":">aaaa</a></p>')
self.assertEqual(
response_1, '<p><a href=":" rel="noopener noreferrer">aaaa</a></p>'
)

xss_payload_2 = '![" onerror=alert(1) ](x)'
response_2 = markdownify(xss_payload_2)
Expand All @@ -125,7 +130,7 @@ def test_markdownify_xss_handled(self):
response_3 = markdownify(xss_payload_3)
self.assertEqual(
response_3,
'<p><a href="&quot; onmouseover=alert(document.domain)">xss</a>)</p>', # noqa: E501
'<p><a href="&quot; onmouseover=alert(document.domain)" rel="noopener noreferrer">xss</a>)</p>', # noqa: E501
)

def test_urls(self):
Expand Down
8 changes: 4 additions & 4 deletions martor/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import re
import bleach
import nh3

from django.utils.functional import Promise
from django.core.serializers.json import DjangoJSONEncoder
Expand Down Expand Up @@ -33,7 +33,7 @@ def markdownify(markdown_text):
# Sanitize Markdown links
# https://github.com/netbox-community/netbox/commit/5af2b3c2f577a01d177cb24cda1019551a2a4b64
schemes = "|".join(ALLOWED_URL_SCHEMES)
pattern = fr"\[(.+)\]\((?!({schemes})).*(:|;)(.+)\)"
pattern = rf"\[(.+)\]\((?!({schemes})).*(:|;)(.+)\)"
markdown_text = re.sub(
pattern,
"[\\1](\\3)",
Expand All @@ -46,11 +46,11 @@ def markdownify(markdown_text):
extensions=MARTOR_MARKDOWN_EXTENSIONS,
extension_configs=MARTOR_MARKDOWN_EXTENSION_CONFIGS,
)
return bleach.clean(
return nh3.clean(
html,
tags=ALLOWED_HTML_TAGS,
attributes=ALLOWED_HTML_ATTRIBUTES,
protocols=ALLOWED_URL_SCHEMES,
url_schemes=ALLOWED_URL_SCHEMES,
)


Expand Down
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
urllib3<2 ; python_version < '3.7' # urllib3 2.0 dropped support for Python 3.6
zipp<3.7 ; python_version < '3.7' # zipp 3.7.0 dropped support for Python 3.6
importlib_metadata<4.9 # # importlib_metadata 4.9.0 dropped support for Python 3.6
importlib_metadata<4.9 # importlib_metadata 4.9.0 dropped support for Python 3.6
Django>=3.2
Markdown<3.4
requests
bleach
requests>=2.12.4
nh3==0.2.14 # https://github.com/messense/nh3
tzdata

0 comments on commit ed8f7b3

Please sign in to comment.