mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #14116 from cinaglia/fix-singlestat-xss
Mitigate XSS vulnerabilities in Singlestat panel
This commit is contained in:
commit
c856c21b77
@ -77,7 +77,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor($scope, $injector, private linkSrv) {
|
constructor($scope, $injector, private linkSrv, private $sanitize) {
|
||||||
super($scope, $injector);
|
super($scope, $injector);
|
||||||
_.defaults(this.panel, this.panelDefaults);
|
_.defaults(this.panel, this.panelDefaults);
|
||||||
|
|
||||||
@ -398,14 +398,15 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|||||||
const $location = this.$location;
|
const $location = this.$location;
|
||||||
const linkSrv = this.linkSrv;
|
const linkSrv = this.linkSrv;
|
||||||
const $timeout = this.$timeout;
|
const $timeout = this.$timeout;
|
||||||
|
const $sanitize = this.$sanitize;
|
||||||
const panel = ctrl.panel;
|
const panel = ctrl.panel;
|
||||||
const templateSrv = this.templateSrv;
|
const templateSrv = this.templateSrv;
|
||||||
let data, linkInfo;
|
let data, linkInfo;
|
||||||
const $panelContainer = elem.find('.panel-container');
|
const $panelContainer = elem.find('.panel-container');
|
||||||
elem = elem.find('.singlestat-panel');
|
elem = elem.find('.singlestat-panel');
|
||||||
|
|
||||||
function applyColoringThresholds(value, valueString) {
|
function applyColoringThresholds(valueString) {
|
||||||
const color = getColorForValue(data, value);
|
const color = getColorForValue(data, data.value);
|
||||||
if (color) {
|
if (color) {
|
||||||
return '<span style="color:' + color + '">' + valueString + '</span>';
|
return '<span style="color:' + color + '">' + valueString + '</span>';
|
||||||
}
|
}
|
||||||
@ -413,8 +414,9 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|||||||
return valueString;
|
return valueString;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSpan(className, fontSize, value) {
|
function getSpan(className, fontSize, applyColoring, value) {
|
||||||
value = templateSrv.replace(value, data.scopedVars);
|
value = $sanitize(templateSrv.replace(value, data.scopedVars));
|
||||||
|
value = applyColoring ? applyColoringThresholds(value) : value;
|
||||||
return '<span class="' + className + '" style="font-size:' + fontSize + '">' + value + '</span>';
|
return '<span class="' + className + '" style="font-size:' + fontSize + '">' + value + '</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,25 +424,13 @@ class SingleStatCtrl extends MetricsPanelCtrl {
|
|||||||
let body = '<div class="singlestat-panel-value-container">';
|
let body = '<div class="singlestat-panel-value-container">';
|
||||||
|
|
||||||
if (panel.prefix) {
|
if (panel.prefix) {
|
||||||
let prefix = panel.prefix;
|
body += getSpan('singlestat-panel-prefix', panel.prefixFontSize, panel.colorPrefix, panel.prefix);
|
||||||
if (panel.colorPrefix) {
|
|
||||||
prefix = applyColoringThresholds(data.value, panel.prefix);
|
|
||||||
}
|
|
||||||
body += getSpan('singlestat-panel-prefix', panel.prefixFontSize, prefix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = data.valueFormatted;
|
body += getSpan('singlestat-panel-value', panel.valueFontSize, panel.colorValue, data.valueFormatted);
|
||||||
if (panel.colorValue) {
|
|
||||||
value = applyColoringThresholds(data.value, value);
|
|
||||||
}
|
|
||||||
body += getSpan('singlestat-panel-value', panel.valueFontSize, value);
|
|
||||||
|
|
||||||
if (panel.postfix) {
|
if (panel.postfix) {
|
||||||
let postfix = panel.postfix;
|
body += getSpan('singlestat-panel-postfix', panel.postfixFontSize, panel.colorPostfix, panel.postfix);
|
||||||
if (panel.colorPostfix) {
|
|
||||||
postfix = applyColoringThresholds(data.value, panel.postfix);
|
|
||||||
}
|
|
||||||
body += getSpan('singlestat-panel-postfix', panel.postfixFontSize, postfix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body += '</div>';
|
body += '</div>';
|
||||||
|
@ -14,6 +14,8 @@ describe('SingleStatCtrl', () => {
|
|||||||
get: () => {},
|
get: () => {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const $sanitize = {};
|
||||||
|
|
||||||
SingleStatCtrl.prototype.panel = {
|
SingleStatCtrl.prototype.panel = {
|
||||||
events: {
|
events: {
|
||||||
on: () => {},
|
on: () => {},
|
||||||
@ -31,7 +33,7 @@ describe('SingleStatCtrl', () => {
|
|||||||
describe(desc, () => {
|
describe(desc, () => {
|
||||||
ctx.setup = setupFunc => {
|
ctx.setup = setupFunc => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
ctx.ctrl = new SingleStatCtrl($scope, $injector, {});
|
ctx.ctrl = new SingleStatCtrl($scope, $injector, {}, $sanitize);
|
||||||
setupFunc();
|
setupFunc();
|
||||||
ctx.ctrl.onDataReceived(ctx.data);
|
ctx.ctrl.onDataReceived(ctx.data);
|
||||||
ctx.data = ctx.ctrl.data;
|
ctx.data = ctx.ctrl.data;
|
||||||
|
Loading…
Reference in New Issue
Block a user