diff --git a/requirements/base.txt b/requirements/base.txt index c07c1bc51..7b23436f2 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -25,8 +25,6 @@ bcrypt==4.0.1 # via paramiko billiard==3.6.4.0 # via celery -bleach==3.3.1 - # via apache-superset brotli==1.0.9 # via flask-compress cachelib==0.4.1 @@ -182,6 +180,8 @@ mdurl==0.1.2 # via markdown-it-py msgpack==1.0.2 # via apache-superset +nh3==0.2.11 + # via apache-superset numpy==1.23.5 # via # apache-superset @@ -191,7 +191,6 @@ ordered-set==4.1.0 # via flask-limiter packaging==21.3 # via - # bleach # deprecation # limits pandas==1.5.3 @@ -265,7 +264,6 @@ simplejson==3.17.3 # via apache-superset six==1.16.0 # via - # bleach # click-repl # isodate # jsonschema @@ -308,8 +306,6 @@ vine==5.0.0 # kombu wcwidth==0.2.5 # via prompt-toolkit -webencodings==0.5.1 - # via bleach werkzeug==2.1.2 # via # flask diff --git a/setup.cfg b/setup.cfg index a9470d51b..970fd4ca8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,7 +30,7 @@ combine_as_imports = true include_trailing_comma = true line_length = 88 known_first_party = superset -known_third_party =alembic,apispec,backoff,bleach,cachelib,celery,click,colorama,cron_descriptor,croniter,cryptography,dateutil,deprecation,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_jwt_extended,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,freezegun,geohash,geopy,graphlib,holidays,humanize,isodate,jinja2,jwt,markdown,markupsafe,marshmallow,marshmallow_enum,msgpack,numpy,pandas,parameterized,parsedatetime,pgsanity,pkg_resources,polyline,prison,progress,pyarrow,sqlalchemy_bigquery,pyhive,pyparsing,pytest,pytest_mock,pytz,redis,requests,selenium,setuptools,simplejson,slack,sqlalchemy,sqlalchemy_utils,sqlparse,typing_extensions,urllib3,werkzeug,wtforms,wtforms_json,yaml +known_third_party =alembic,apispec,backoff,cachelib,celery,click,colorama,cron_descriptor,croniter,cryptography,dateutil,deprecation,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_jwt_extended,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,freezegun,geohash,geopy,graphlib,holidays,humanize,isodate,jinja2,jwt,markdown,markupsafe,marshmallow,marshmallow_enum,msgpack,nh3,numpy,pandas,parameterized,parsedatetime,pgsanity,pkg_resources,polyline,prison,progress,pyarrow,sqlalchemy_bigquery,pyhive,pyparsing,pytest,pytest_mock,pytz,redis,requests,selenium,setuptools,simplejson,slack,sqlalchemy,sqlalchemy_utils,sqlparse,typing_extensions,urllib3,werkzeug,wtforms,wtforms_json,yaml multi_line_output = 3 order_by_type = false diff --git a/setup.py b/setup.py index 8202d066d..8d2fdfdc4 100644 --- a/setup.py +++ b/setup.py @@ -73,7 +73,6 @@ setup( }, install_requires=[ "backoff>=1.8.0", - "bleach>=3.0.2, <4.0.0", "cachelib>=0.4.1,<0.5", "celery>=5.2.2, <6.0.0", "click>=8.0.3", @@ -101,6 +100,7 @@ setup( "isodate", "markdown>=3.0", "msgpack>=1.0.0, <1.1", + "nh3>=0.2.11, <0.3", "numpy==1.23.5", "pandas>=1.5.3, <1.6", "parsedatetime", diff --git a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx index f56c9c9cd..0f151ff4f 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Chart.jsx @@ -459,10 +459,10 @@ class Chart extends React.Component { {/* This usage of dangerouslySetInnerHTML is safe since it is being used to render - markdown that is sanitized with bleach. See: + markdown that is sanitized with nh3. See: https://github.com/apache/superset/pull/4390 and - https://github.com/apache/superset/commit/b6fcc22d5a2cb7a5e92599ed5795a0169385a825 + https://github.com/apache/superset/pull/23862 */} {isExpanded && slice.description_markeddown && (
str: def markdown(raw: str, markup_wrap: Optional[bool] = False) -> str: - safe_markdown_tags = [ + safe_markdown_tags = { "h1", "h2", "h3", @@ -690,10 +690,10 @@ def markdown(raw: str, markup_wrap: Optional[bool] = False) -> str: "dt", "img", "a", - ] + } safe_markdown_attrs = { - "img": ["src", "alt", "title"], - "a": ["href", "alt", "title"], + "img": {"src", "alt", "title"}, + "a": {"href", "alt", "title"}, } safe = md.markdown( raw or "", @@ -703,7 +703,8 @@ def markdown(raw: str, markup_wrap: Optional[bool] = False) -> str: "markdown.extensions.codehilite", ], ) - safe = bleach.clean(safe, safe_markdown_tags, safe_markdown_attrs) + # pylint: disable=no-member + safe = nh3.clean(safe, tags=safe_markdown_tags, attributes=safe_markdown_attrs) if markup_wrap: safe = Markup(safe) return safe diff --git a/tests/unit_tests/notifications/email_tests.py b/tests/unit_tests/notifications/email_tests.py index 4ce34b99c..697a9bac4 100644 --- a/tests/unit_tests/notifications/email_tests.py +++ b/tests/unit_tests/notifications/email_tests.py @@ -50,5 +50,8 @@ def test_render_description_with_html() -> None: ._get_content() .body ) - assert '

This is a test alert


' in email_body + assert ( + '

This is a test alert


' + in email_body + ) assert '<a href="http://www.example.com">333</a>' in email_body