-
Notifications
You must be signed in to change notification settings - Fork 13.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Improves SafeMarkdown HTML sanitization #21895
feat: Improves SafeMarkdown HTML sanitization #21895
Conversation
17080a2
to
1180ec3
Compare
Codecov Report
@@ Coverage Diff @@
## master #21895 +/- ##
==========================================
- Coverage 67.03% 66.11% -0.93%
==========================================
Files 1813 1813
Lines 69424 69426 +2
Branches 7448 7448
==========================================
- Hits 46541 45898 -643
- Misses 20963 21608 +645
Partials 1920 1920
Flags with carried forward coverage won't be shown. Click here to find out more.
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
e01fee2
to
582f34e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM and tested the schema overrides to work as expected. Thanks for doing this, this is a really important enhancement.
It would be nice to follow-up with a PR that adds test coverage (I'm surprised the CI coverage test for superset-ui/core
didn't complain about this; @zhaoyongjie do you know?)
function SafeMarkdown({ | ||
source, | ||
htmlSanitization = true, | ||
htmlSchemaOverrides = {}, | ||
}: SafeMarkdownProps) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be nice to have RTL tests that test something along the following lines:
- the default use case where source is rendering correctly
- sanitization is disabled -> how do things change
- a schema override before and after
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll work on this in a follow-up 👍🏼
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@villebro superset-ui/core
only guarantee 100% coverage on the js/ts
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@villebro
superset-ui/core
only guarantee 100% coverage on thejs/ts
file.
Oh right! Thanks for following up @zhaoyongjie ! 👍
const displayHtml = isFeatureEnabled(FeatureFlag.DISPLAY_MARKDOWN_HTML); | ||
const escapeHtml = isFeatureEnabled(FeatureFlag.ESCAPE_MARKDOWN_HTML); | ||
|
||
const rehypePlugins = useMemo(() => { | ||
const rehypePlugins: any = []; | ||
if (displayHtml && !escapeHtml) { | ||
rehypePlugins.push(rehypeRaw); | ||
if (htmlSanitization) { | ||
const schema = merge(defaultSchema, htmlSchemaOverrides); | ||
rehypePlugins.push([rehypeSanitize, schema]); | ||
} | ||
} | ||
return rehypePlugins; | ||
}, [displayHtml, escapeHtml, htmlSanitization, htmlSchemaOverrides]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of unrelated comment, but just thinking out loud: as the feature flags here are constant (they're populated from bootstrap data at load time), displayHtml
and escapeHtml
are both constants, hence won't really change and are kind of redundant in the dep array. But it would be cool to make something like
const displayHtml = useFeatureFlag(FeatureFlag.DISPLAY_MARKDOWN_HTML);
which could change dynamically, in which case they would also be more relevant in the dep array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I was thinking the same thing here 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @villebro @michael-s-molina, I thought the dynamic feature flag might not be a good approach. The reason is that
- There are some FF not only on the frontend but also on the backend. for example,
ENABLE_TEMPLATE_PROCESSING
. so it's hard to set a FF by dynamic. - Some FF is designed for security, for example,
ENABLE_EXPLORE_JSON_CSRF_PROTECTION
,
ENABLE_TEMPLATE_PROCESSING
, andENABLE_TEMPLATE_REMOVE_FILTERS
. The system administrator does not allow users to modify these config dynamically.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think all of these problems can be addressed in a future configuration module. We can choose what properties we expose to the module and also add the necessary logic to change backend flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I think we should create a new concept to handle user settings.
This reverts commit 7d1df3b.
This reverts commit 7d1df3b.
SUMMARY
Currently, we are rendering HTML by default and using the following function to sanitize the content:
This only blocks a small subset of potential attack vectors as you can easily see here. To improve the component's security this PR does the following:
HTML_SANITIZATION
configuration option to enable/disable HTML sanitization.HTML_SANITIZATION_SCHEMA_EXTENSIONS
configuration option to extend the default schema in case someone has a controlled environment and wishes to use some blocked elements/attributes.TESTING INSTRUCTIONS
HTML_SANITIZATION
HTML_SANITIZATION_SCHEMA_EXTENSIONS
ADDITIONAL INFORMATION