From cfc67a9e2df0c2757b7fdb3d5b2e6a9c9eeab562 Mon Sep 17 00:00:00 2001 From: Esteban Beltran Date: Mon, 20 Nov 2023 12:00:31 +0100 Subject: [PATCH] Sandbox: do not load grafana signed app plugins into the sandbox (#78334) * Sandbox: do not load grafana signed app plugins into the sandbox * remove unused dependency --- public/app/features/plugins/plugin_loader.ts | 2 +- public/app/features/plugins/sandbox/utils.ts | 47 +++++++++++++++----- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/public/app/features/plugins/plugin_loader.ts b/public/app/features/plugins/plugin_loader.ts index 038b54be04f..b4599eca1bc 100644 --- a/public/app/features/plugins/plugin_loader.ts +++ b/public/app/features/plugins/plugin_loader.ts @@ -68,7 +68,7 @@ export async function importPluginModule({ } // the sandboxing environment code cannot work in nodejs and requires a real browser - if (isFrontendSandboxSupported({ isAngular, pluginId })) { + if (await isFrontendSandboxSupported({ isAngular, pluginId })) { return importPluginModuleInSandbox({ pluginId }); } diff --git a/public/app/features/plugins/sandbox/utils.ts b/public/app/features/plugins/sandbox/utils.ts index 74305e594e4..14bd3f2f889 100644 --- a/public/app/features/plugins/sandbox/utils.ts +++ b/public/app/features/plugins/sandbox/utils.ts @@ -1,9 +1,12 @@ import { isNearMembraneProxy } from '@locker/near-membrane-shared'; import React from 'react'; +import { PluginSignatureType, PluginType } from '@grafana/data'; import { LogContext } from '@grafana/faro-web-sdk'; import { logWarning as logWarningRuntime, logError as logErrorRuntime, config } from '@grafana/runtime'; +import { getPluginSettings } from '../pluginSettings'; + import { SandboxedPluginObject } from './types'; const monitorOnly = Boolean(config.featureToggles.frontendSandboxMonitorOnly); @@ -38,23 +41,47 @@ export function logError(error: Error, context?: LogContext) { logErrorRuntime(error, context); } -export function isFrontendSandboxSupported({ +export async function isFrontendSandboxSupported({ isAngular, pluginId, }: { isAngular?: boolean; pluginId: string; -}): boolean { +}): Promise { + // Only if the feature is not enabled no support for sandbox + if (!Boolean(config.featureToggles.pluginsFrontendSandbox)) { + return false; + } + + // no support for angular plugins + if (isAngular) { + return false; + } + // To fast test and debug the sandbox in the browser. - const sandboxQueryParam = location.search.includes('nosandbox') && config.buildInfo.env === 'development'; + const sandboxDisableQueryParam = location.search.includes('nosandbox') && config.buildInfo.env === 'development'; + if (sandboxDisableQueryParam) { + return false; + } + + // if disabled by configuration const isPluginExcepted = config.disableFrontendSandboxForPlugins.includes(pluginId); - return ( - !isAngular && - Boolean(config.featureToggles.pluginsFrontendSandbox) && - process.env.NODE_ENV !== 'test' && - !isPluginExcepted && - !sandboxQueryParam - ); + if (isPluginExcepted) { + return false; + } + + // no sandbox in test mode. it often breaks e2e tests + if (process.env.NODE_ENV === 'test') { + return false; + } + + // we don't run grafana-own apps in the sandbox + const pluginMeta = await getPluginSettings(pluginId); + if (pluginMeta.type === PluginType.app && pluginMeta.signatureType === PluginSignatureType.grafana) { + return false; + } + + return true; } function isRegex(value: unknown): value is RegExp {