diff --git a/public/app/features/templating/specs/template_srv.test.ts b/public/app/features/templating/specs/template_srv.test.ts
index 4d2f4accd6c..eda529815de 100644
--- a/public/app/features/templating/specs/template_srv.test.ts
+++ b/public/app/features/templating/specs/template_srv.test.ts
@@ -268,6 +268,14 @@ describe('templateSrv', () => {
});
});
+ describe('html format', () => {
+ it('should encode values html escape sequences', () => {
+ initTemplateSrv([{ type: 'query', name: 'test', current: { value: '' } }]);
+ const target = _templateSrv.replace('$test', {}, 'html');
+ expect(target).toBe('<script>alert(asd)</script>');
+ });
+ });
+
describe('format variable to string values', () => {
it('single value should return value', () => {
const result = _templateSrv.formatValue('test');
diff --git a/public/app/features/templating/template_srv.ts b/public/app/features/templating/template_srv.ts
index d35e7241649..93287ab1c25 100644
--- a/public/app/features/templating/template_srv.ts
+++ b/public/app/features/templating/template_srv.ts
@@ -1,6 +1,7 @@
import kbn from 'app/core/utils/kbn';
import _ from 'lodash';
import { variableRegex } from 'app/features/templating/variable';
+import { escapeHtml } from 'app/core/utils/text';
import { ScopedVars, TimeRange } from '@grafana/data';
function luceneEscape(value: string) {
@@ -165,6 +166,12 @@ export class TemplateSrv {
}
return value;
}
+ case 'html': {
+ if (_.isArray(value)) {
+ return escapeHtml(value.join(', '));
+ }
+ return escapeHtml(value);
+ }
case 'json': {
return JSON.stringify(value);
}
diff --git a/public/app/plugins/panel/text/module.ts b/public/app/plugins/panel/text/module.ts
index 8456de471d0..8fed0cb339e 100644
--- a/public/app/plugins/panel/text/module.ts
+++ b/public/app/plugins/panel/text/module.ts
@@ -89,13 +89,13 @@ export class TextPanelCtrl extends PanelCtrl {
}
updateContent(html: string) {
- html = config.disableSanitizeHtml ? html : sanitize(html);
try {
- this.content = this.$sce.trustAsHtml(this.templateSrv.replace(html, this.panel.scopedVars));
+ html = this.templateSrv.replace(html, this.panel.scopedVars, 'html');
} catch (e) {
console.log('Text panel error: ', e);
- this.content = this.$sce.trustAsHtml(html);
}
+
+ this.content = this.$sce.trustAsHtml(config.disableSanitizeHtml ? html : sanitize(html));
}
}
diff --git a/public/app/plugins/panel/text2/TextPanel.tsx b/public/app/plugins/panel/text2/TextPanel.tsx
index 67bb2d4daf3..cd6d202ebfd 100644
--- a/public/app/plugins/panel/text2/TextPanel.tsx
+++ b/public/app/plugins/panel/text2/TextPanel.tsx
@@ -41,9 +41,9 @@ export class TextPanel extends PureComponent {
prepareHTML(html: string): string {
const { replaceVariables } = this.props;
- html = config.disableSanitizeHtml ? html : sanitize(html);
+ html = replaceVariables(html, {}, 'html');
- return replaceVariables(html);
+ return config.disableSanitizeHtml ? html : sanitize(html);
}
prepareText(content: string): string {