Files
bongo/src/www/tests/test_html_mail.py
T
2026-07-19 18:25:32 +02:00

82 lines
3.4 KiB
Python

# /****************************************************************************
# * <Novell-copyright>
# * Copyright (c) 2001 Novell, Inc. All Rights Reserved.
# *
# * This program is free software; you can redistribute it and/or
# * modify it under the terms of version 2 of the GNU General Public License
# * as published by the Free Software Foundation.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, contact Novell, Inc.
# *
# * To contact Novell about this file by physical or electronic mail, you
# * may find current contact information at www.novell.com.
# * </Novell-copyright>
# ****************************************************************************/
import unittest
from bongo_web.html_mail import sanitize_html
def exercising_cleaner(html, **options):
"""Exercise the URL callback without duplicating nh3's HTML parser."""
callback = options["attribute_filter"]
values = [
callback("img", "src", "cid:logo@example"),
callback("img", "src", "https://tracker.example/pixel.gif"),
callback("img", "src", "javascript:alert(1)"),
callback("a", "href", "https://example.test/"),
callback("a", "href", "javascript:alert(1)"),
]
return "|".join(value or "REMOVED" for value in values)
class HtmlMailTests(unittest.TestCase):
def test_keeps_inline_and_marks_remote_images(self):
result = sanitize_html("<p>mail</p>", exercising_cleaner)
self.assertIn("cid:logo@example", result["html"])
self.assertIn("bongo-remote:0", result["html"])
self.assertIn("REMOVED", result["html"])
self.assertEqual(result["remote_images"],
["https://tracker.example/pixel.gif"])
def test_rejects_oversized_html(self):
with self.assertRaises(ValueError):
sanitize_html("x" * (4 * 1024 * 1024 + 1), exercising_cleaner)
def test_real_sanitizer_removes_active_content_and_unsafe_css(self):
result = sanitize_html(
'<p style="color:red;position:fixed;background-image:url(x)">ok'
'<script>alert(1)</script><img src="cid:logo">'
'<img src="https://tracker.example/pixel">'
'<a href="javascript:alert(2)">bad</a></p>')
output = result["html"]
self.assertNotIn("alert", output)
self.assertNotIn("position", output)
self.assertNotIn("background-image", output)
self.assertIn('style="color:red"', output)
self.assertIn('src="cid:logo"', output)
self.assertIn('src="bongo-remote:0"', output)
self.assertEqual(result["remote_images"],
["https://tracker.example/pixel"])
def test_style_filter_rejects_obfuscated_and_active_values(self):
result = sanitize_html(
'<p style="color:e\\78pression(alert(1));'
'background-color:url(https://tracker.example/pixel);'
'font-weight:bold">safe</p>')
output = result["html"]
self.assertNotIn("expression", output)
self.assertNotIn("url", output)
self.assertIn("font-weight:bold", output)
if __name__ == "__main__":
unittest.main()