django-markdown-editor
django-markdown-editor copied to clipboard
XSS via href content
The bug reported here https://github.com/agusmakmun/django-markdown-editor/issues/173 can be extended to an href content with small syntax changes.
Steps to reproduce
- editor insert: [testlinkxss](" onmouseover=alert(document.domain) l)
- preview will result in:
<a href="" onmouseover="alert(document.domain)" l"="">testlinkxss
- go with the mouse over will trigger the payload.
@Arkango you correct, that's why we marked it as "help wanted", feel free to contribute the code if you have any solution for it.
@agusmakmun I tested the regex https://regex101.com/r/fUvNyq/1 with our payload executed here https://github.com/agusmakmun/django-markdown-editor/blob/master/martor/utils.py#L33 there isn't a match edit the regex to properly identify links and avoid \
good catch @Arkango, but as you know here by default all markdown content will be rendered from an existing renderer. So, the only things that we can do is only replacing the vulnerability text, so that's why we did re.sub(..) to handle it.
Well if you replace .* and .+ with only valid url characters like this [^-]_.~!*'();:@&=+$,/?%#[A-z0-9] , look at this solution proposed here https://stackoverflow.com/questions/22038142/regex-for-valid-url-characters no backslash is included
@Arkango I still didn't get it, can you please create a pull request, so I can check it out.
Now finally we solve this issue by using bleach, thank you @eelkevdbos for the recommendation. Please upgrade your package by using this command:
pip install martor --upgrade
meanwhile, I already provide the unitest as well which related with xss issues:
https://github.com/agusmakmun/django-markdown-editor/blob/master/martor/tests/tests.py#L80
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>')
xss_payload_2 = ''
response_2 = markdownify(xss_payload_2)
self.assertEqual(
response_2, '<p><img alt="" onerror=alert(1) " src="x"></p>'
)
xss_payload_3 = '[xss](" onmouseover=alert(document.domain) l)'
response_3 = markdownify(xss_payload_3)
self.assertEqual(
response_3,
'<p><a href="" onmouseover=alert(document.domain)">xss</a>)</p>', # noqa: E501
)