mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Marked: Upgrade and always sanitize by default (#28796)
* Marked: Upgrade and always sanitize by default * Added test * corrected text panel logic
This commit is contained in:
parent
2f77e611cb
commit
c3ed644f66
@ -95,7 +95,6 @@
|
||||
"@types/jquery": "3.3.38",
|
||||
"@types/lodash": "4.14.149",
|
||||
"@types/lru-cache": "^5.1.0",
|
||||
"@types/marked": "1.1.0",
|
||||
"@types/moment-timezone": "0.5.13",
|
||||
"@types/mousetrap": "1.6.3",
|
||||
"@types/node": "13.7.0",
|
||||
@ -247,7 +246,6 @@
|
||||
"jsurl": "^0.1.5",
|
||||
"lodash": "4.17.19",
|
||||
"lru-cache": "^5.1.1",
|
||||
"marked": "1.1.1",
|
||||
"md5": "^2.2.1",
|
||||
"memoize-one": "5.1.1",
|
||||
"moment": "2.24.0",
|
||||
|
@ -28,6 +28,7 @@
|
||||
"eventemitter3": "4.0.7",
|
||||
"lodash": "4.17.19",
|
||||
"rxjs": "6.6.3",
|
||||
"marked": "1.2.2",
|
||||
"xss": "1.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -40,6 +41,7 @@
|
||||
"@types/jquery": "3.3.38",
|
||||
"@types/lodash": "4.14.123",
|
||||
"@types/node": "10.14.1",
|
||||
"@types/marked": "1.1.0",
|
||||
"@types/papaparse": "5.2.0",
|
||||
"@types/react": "16.8.16",
|
||||
"@types/rollup-plugin-visualizer": "2.6.0",
|
||||
|
@ -5,4 +5,9 @@ describe('Markdown wrapper', () => {
|
||||
const str = renderMarkdown(undefined);
|
||||
expect(str).toBe('');
|
||||
});
|
||||
|
||||
it('should sanitize by default', () => {
|
||||
const str = renderMarkdown('<script>alert()</script>');
|
||||
expect(str).toBe('<script>alert()</script>');
|
||||
});
|
||||
});
|
||||
|
@ -1,19 +1,28 @@
|
||||
import marked, { MarkedOptions } from 'marked';
|
||||
import marked from 'marked';
|
||||
import { sanitize } from './sanitize';
|
||||
|
||||
const defaultMarkedOptions: MarkedOptions = {
|
||||
renderer: new marked.Renderer(),
|
||||
pedantic: false,
|
||||
gfm: true,
|
||||
sanitize: true,
|
||||
smartLists: true,
|
||||
smartypants: false,
|
||||
xhtml: false,
|
||||
};
|
||||
let hasInitialized = false;
|
||||
|
||||
export function setMarkdownOptions(optionsOverride?: MarkedOptions) {
|
||||
marked.setOptions({ ...defaultMarkedOptions, ...optionsOverride });
|
||||
export interface RenderMarkdownOptions {
|
||||
noSanitize?: boolean;
|
||||
}
|
||||
|
||||
export function renderMarkdown(str?: string): string {
|
||||
return marked(str || '');
|
||||
export function renderMarkdown(str?: string, options?: RenderMarkdownOptions): string {
|
||||
if (!hasInitialized) {
|
||||
marked.setOptions({
|
||||
pedantic: false,
|
||||
gfm: true,
|
||||
smartLists: true,
|
||||
smartypants: false,
|
||||
xhtml: false,
|
||||
});
|
||||
hasInitialized = true;
|
||||
}
|
||||
|
||||
const html = marked(str || '');
|
||||
if (options?.noSanitize) {
|
||||
return html;
|
||||
}
|
||||
|
||||
return sanitize(html);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import React, { useContext } from 'react';
|
||||
import { css, cx } from 'emotion';
|
||||
|
||||
import { CompletionItem, selectThemeVariant, ThemeContext } from '../..';
|
||||
import { GrafanaTheme, renderMarkdown, textUtil } from '@grafana/data';
|
||||
import { GrafanaTheme, renderMarkdown } from '@grafana/data';
|
||||
|
||||
const getStyles = (theme: GrafanaTheme, height: number, visible: boolean) => {
|
||||
return {
|
||||
@ -41,7 +41,7 @@ interface Props {
|
||||
export const TypeaheadInfo: React.FC<Props> = ({ item, height }) => {
|
||||
const visible = item && !!item.documentation;
|
||||
const label = item ? item.label : '';
|
||||
const documentation = textUtil.sanitize(renderMarkdown(item?.documentation));
|
||||
const documentation = renderMarkdown(item?.documentation);
|
||||
const theme = useContext(ThemeContext);
|
||||
const styles = getStyles(theme, height, visible);
|
||||
|
||||
|
@ -28,7 +28,6 @@ import _ from 'lodash';
|
||||
import {
|
||||
AppEvents,
|
||||
setLocale,
|
||||
setMarkdownOptions,
|
||||
standardEditorsRegistry,
|
||||
standardFieldConfigEditorRegistry,
|
||||
standardTransformersRegistry,
|
||||
@ -97,8 +96,6 @@ export class GrafanaApp {
|
||||
setLocale(config.bootData.user.locale);
|
||||
setTimeZoneResolver(() => config.bootData.user.timezone);
|
||||
|
||||
setMarkdownOptions({ sanitize: !config.disableSanitizeHtml });
|
||||
|
||||
standardEditorsRegistry.setInit(getStandardOptionEditors);
|
||||
standardFieldConfigEditorRegistry.setInit(getStandardFieldConfigs);
|
||||
standardTransformersRegistry.setInit(getStandardTransformers);
|
||||
|
@ -43,7 +43,8 @@ export class TextPanel extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
prepareMarkdown(content: string): string {
|
||||
return renderMarkdown(this.interpolateAndSanitizeString(content));
|
||||
// Sanitize is disabled here as we handle that after variable interpolation
|
||||
return renderMarkdown(this.interpolateAndSanitizeString(content), { noSanitize: config.disableSanitizeHtml });
|
||||
}
|
||||
|
||||
interpolateAndSanitizeString(content: string): string {
|
||||
|
@ -18229,10 +18229,10 @@ markdown-to-jsx@^6.11.4:
|
||||
prop-types "^15.6.2"
|
||||
unquote "^1.1.0"
|
||||
|
||||
marked@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-1.1.1.tgz#e5d61b69842210d5df57b05856e0c91572703e6a"
|
||||
integrity sha512-mJzT8D2yPxoPh7h0UXkB+dBj4FykPJ2OIfxAWeIHrvoHDkFxukV/29QxoFQoPM6RLEwhIFdJpmKBlqVM3s2ZIw==
|
||||
marked@1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.2.tgz#5d77ffb789c4cb0ae828bfe76250f7140b123f70"
|
||||
integrity sha512-5jjKHVl/FPo0Z6ocP3zYhKiJLzkwJAw4CZoLjv57FkvbUuwOX4LIBBGGcXjAY6ATcd1q9B8UTj5T9Umauj0QYQ==
|
||||
|
||||
marked@^0.3.12:
|
||||
version "0.3.19"
|
||||
|
Loading…
Reference in New Issue
Block a user