Frontend Sandbox: Use DOMPurify to sanitize innerHTML (#102302)
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { ProxyTarget } from '@locker/near-membrane-shared';
|
import { ProxyTarget } from '@locker/near-membrane-shared';
|
||||||
|
import DOMPurify from 'dompurify';
|
||||||
import { cloneDeep, isFunction } from 'lodash';
|
import { cloneDeep, isFunction } from 'lodash';
|
||||||
|
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
@@ -203,7 +204,8 @@ function distortInnerHTML(distortions: DistortionMap) {
|
|||||||
function getInnerHTMLDistortion(originalMethod: unknown, meta: SandboxPluginMeta) {
|
function getInnerHTMLDistortion(originalMethod: unknown, meta: SandboxPluginMeta) {
|
||||||
const pluginId = meta.id;
|
const pluginId = meta.id;
|
||||||
return function innerHTMLDistortion(this: HTMLElement, ...args: string[]) {
|
return function innerHTMLDistortion(this: HTMLElement, ...args: string[]) {
|
||||||
for (const arg of args) {
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
const arg = args[i];
|
||||||
// NOTE: DOMPurify anti-tamper mechanism requires us to clone the string
|
// NOTE: DOMPurify anti-tamper mechanism requires us to clone the string
|
||||||
// calling any method whatsoever on a string will cause the string to be tampered
|
// calling any method whatsoever on a string will cause the string to be tampered
|
||||||
// and DOMPurify will return empty strings
|
// and DOMPurify will return empty strings
|
||||||
@@ -223,6 +225,16 @@ function distortInnerHTML(distortions: DistortionMap) {
|
|||||||
throw new Error('<' + forbiddenElement + '> is not allowed in sandboxed plugins');
|
throw new Error('<' + forbiddenElement + '> is not allowed in sandboxed plugins');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// prevent some dom operations that use direct callbacks
|
||||||
|
if (lowerCase.match(/onerror|onload|onsuccess|onbeforeunload/)) {
|
||||||
|
logWarning(`Plugin ${pluginId} tried to set forbidden attribute in innerHTML`, {
|
||||||
|
pluginId,
|
||||||
|
attrOrMethod: 'innerHTML',
|
||||||
|
param: arg,
|
||||||
|
entity: 'HTMLElement',
|
||||||
|
});
|
||||||
|
args[i] = DOMPurify.sanitize(args[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFunction(originalMethod)) {
|
if (isFunction(originalMethod)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user