Disallow use of "dangerouslySetInnerHTML" on React components (#17759) (#18565)

Disallows use of "dangerouslySetInnerHTML" on React components, except where explicitly whitelisted
This commit is contained in:
Larry Gregory 2018-04-25 11:58:48 -04:00 committed by GitHub
parent dc6ef763fe
commit 56fe6cbb33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 3 deletions

View file

@ -105,6 +105,7 @@ module.exports = {
'react/jsx-indent-props': ['error', 2],
'react/jsx-max-props-per-line': ['error', { maximum: 1, when: 'multiline' }],
'react/jsx-no-duplicate-props': ['error', { ignoreCase: true }],
'react/no-danger': 'error',
'react/self-closing-comp': 'error',
'react/jsx-wrap-multilines': ['error', {
declaration: true,

View file

@ -37,7 +37,15 @@ class MetricVisValue extends Component {
<div
className="metric-value"
style={metricValueStyle}
dangerouslySetInnerHTML={{ __html: metric.value }}
/*
* Justification for dangerouslySetInnerHTML:
* This is one of the visualizations which makes use of the HTML field formatters.
* Since these formatters produce raw HTML, this visualization needs to be able to render them as-is, relying
* on the field formatter to only produce safe HTML.
* `metric.value` is set by the MetricVisComponent, so this component must make sure this value never contains
* any unsafe HTML (e.g. by bypassing the field formatter).
*/
dangerouslySetInnerHTML={{ __html: metric.value }} //eslint-disable-line react/no-danger
/>
{ showLabel &&
<div>{metric.label}</div>

View file

@ -12,6 +12,10 @@ import MarkdownIt from 'markdown-it';
*/
export function markdownFactory(whiteListedRules, openLinksInNewTab = false) {
let markdownIt;
// It is imperitive that the html config property be set to false, to mitigate XSS: the output of markdown-it is
// fed directly to the DOM via React's dangerouslySetInnerHTML below.
if (whiteListedRules && whiteListedRules.length > 0) {
markdownIt = new MarkdownIt('zero', { html: false, linkify: true });
markdownIt.enable(whiteListedRules);
@ -89,7 +93,12 @@ export class Markdown extends Component {
<div
className={classes}
{...rest}
dangerouslySetInnerHTML={this.state.renderedMarkdown}
/*
* Justification for dangerouslySetInnerHTML:
* The Markdown Visulization is, believe it or not, responsible for rendering Markdown.
* This relies on `markdown-it` to produce safe and correct HTML.
*/
dangerouslySetInnerHTML={this.state.renderedMarkdown} //eslint-disable-line react/no-danger
/>
);
}

View file

@ -349,7 +349,13 @@ Notifier.prototype.banner = function (content = '') {
title="Attention"
iconType="help"
>
<div dangerouslySetInnerHTML={{ __html: markdownIt.render(content) }} />
<div
/*
* Justification for dangerouslySetInnerHTML:
* The notifier relies on `markdown-it` to produce safe and correct HTML.
*/
dangerouslySetInnerHTML={{ __html: markdownIt.render(content) }} //eslint-disable-line react/no-danger
/>
<EuiButton type="primary" size="s" onClick={dismissBanner}>
Dismiss