diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py
--- a/rhodecode/lib/helpers.py
+++ b/rhodecode/lib/helpers.py
@@ -44,7 +44,6 @@ from collections import OrderedDict
import pygments
import itertools
import fnmatch
-import bleach
from datetime import datetime
from functools import partial
@@ -78,6 +77,7 @@ from webhelpers2.number import format_by
from rhodecode.lib._vendor.webhelpers_backports import raw_select
from rhodecode.lib.action_parser import action_parser
+from rhodecode.lib.html_filters import sanitize_html
from rhodecode.lib.pagination import Page, RepoPage, SqlPage
from rhodecode.lib import ext_json
from rhodecode.lib.ext_json import json
@@ -1645,7 +1645,7 @@ def _process_url_func(match_obj, repo_na
'id-repr': issue_id,
'issue-prefix': entry['pref'],
'serv': entry['url'],
- 'title': bleach.clean(desc, strip=True),
+ 'title': sanitize_html(desc, strip=True),
'hovercard_url': hovercard_url
}
diff --git a/rhodecode/lib/html_filters.py b/rhodecode/lib/html_filters.py
--- a/rhodecode/lib/html_filters.py
+++ b/rhodecode/lib/html_filters.py
@@ -16,8 +16,47 @@
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/
+import functools
+import logging
+from .html_sanitizer_defs import markdown_attrs, markdown_tags, all_tags, all_styles
+
+
+log = logging.getLogger(__name__)
+
+
# base64 filter e.g ${ example | base64,n }
def base64(text):
from rhodecode.lib.str_utils import base64_to_str
return base64_to_str(text)
+
+def sanitize_html(text, **kwargs):
+ # TODO: replace this with https://nh3.readthedocs.io/en/latest
+ # bleach is abandoned and deprecated :/
+ import bleach
+ from bleach.css_sanitizer import CSSSanitizer
+
+ css_sanitizer = CSSSanitizer(allowed_css_properties=all_styles)
+
+ markdown = kwargs.pop('markdown', False)
+
+ allowed_attrs = markdown_attrs
+
+ cleaner = functools.partial(bleach.clean,
+ tags=all_tags,
+ attributes=allowed_attrs,
+ css_sanitizer=css_sanitizer,
+ strip_comments=False, **kwargs)
+
+ if markdown:
+ cleaner = functools.partial(bleach.clean,
+ tags=markdown_tags,
+ attributes=markdown_attrs,
+ css_sanitizer=css_sanitizer,
+ strip_comments=False, **kwargs)
+
+ try:
+ return cleaner(text)
+ except Exception:
+ log.exception('Failed to sanitize html')
+ return 'TEXT CANNOT BE PARSED USING HTML SANITIZE'
diff --git a/rhodecode/lib/bleach_whitelist.py b/rhodecode/lib/html_sanitizer_defs.py
rename from rhodecode/lib/bleach_whitelist.py
rename to rhodecode/lib/html_sanitizer_defs.py
--- a/rhodecode/lib/bleach_whitelist.py
+++ b/rhodecode/lib/html_sanitizer_defs.py
@@ -62,7 +62,8 @@ markdown_tags = [
"a",
"input",
"details",
- "summary"
+ "summary",
+ "div"
]
markdown_attrs = {
diff --git a/rhodecode/lib/markup_renderer.py b/rhodecode/lib/markup_renderer.py
--- a/rhodecode/lib/markup_renderer.py
+++ b/rhodecode/lib/markup_renderer.py
@@ -28,7 +28,6 @@ import os
import lxml
import logging
import urllib.parse
-import bleach
import pycmarkgfm
from mako.lookup import TemplateLookup
@@ -40,7 +39,7 @@ from docutils import writers
from docutils.writers import html4css1
import markdown
-from rhodecode.lib.utils2 import safe_str, md5_safe, MENTIONS_REGEX
+from rhodecode.lib.utils2 import safe_str, MENTIONS_REGEX
log = logging.getLogger(__name__)
@@ -271,17 +270,8 @@ class MarkupRenderer(object):
@classmethod
def sanitize_html(cls, text):
- # TODO: replace this with https://nh3.readthedocs.io/en/latest
- # bleach is abandoned and deprecated :/
-
- from .bleach_whitelist import markdown_attrs, markdown_tags
- allowed_tags = markdown_tags
- allowed_attrs = markdown_attrs
-
- try:
- return bleach.clean(text, tags=allowed_tags, attributes=allowed_attrs)
- except Exception:
- return 'TEXT CANNOT BE PARSED USING SANITIZE'
+ from .html_filters import sanitize_html
+ return sanitize_html(text, markdown=True)
@classmethod
def renderer_from_filename(cls, filename, exclude):
diff --git a/rhodecode/model/settings.py b/rhodecode/model/settings.py
--- a/rhodecode/model/settings.py
+++ b/rhodecode/model/settings.py
@@ -21,13 +21,13 @@ import re
import logging
import time
import functools
-import bleach
from collections import namedtuple
from pyramid.threadlocal import get_current_request
from rhodecode.lib import rc_cache
from rhodecode.lib.hash_utils import sha1_safe
+from rhodecode.lib.html_filters import sanitize_html
from rhodecode.lib.utils2 import (
Optional, AttributeDict, safe_str, remove_prefix, str2bool)
from rhodecode.lib.vcs.backends import base
@@ -376,7 +376,7 @@ class IssueTrackerSettingsModel(object):
def url_cleaner(input_str):
input_str = input_str.replace('"', '').replace("'", '')
- input_str = bleach.clean(input_str, strip=True)
+ input_str = sanitize_html(input_str, strip=True)
return input_str
# populate
@@ -394,7 +394,7 @@ class IssueTrackerSettingsModel(object):
'pat_compiled': pat_compiled,
'url': url_cleaner(
qs.get(self._get_keyname('url', uid, 'rhodecode_')) or ''),
- 'pref': bleach.clean(
+ 'pref': sanitize_html(
qs.get(self._get_keyname('pref', uid, 'rhodecode_')) or ''),
'desc': qs.get(
self._get_keyname('desc', uid, 'rhodecode_')),
diff --git a/rhodecode/tests/lib/test_html_sanitizer.py b/rhodecode/tests/lib/test_html_sanitizer.py
new file mode 100644
--- /dev/null
+++ b/rhodecode/tests/lib/test_html_sanitizer.py
@@ -0,0 +1,38 @@
+
+# Copyright (C) 2010-2023 RhodeCode GmbH
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License, version 3
+# (only), 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 Affero General Public License
+# along with this program. If not, see