Plugins: Add config option to exclude specific plugins from frontend sandbox (#70899)

pull/71065/head
Esteban Beltran 2 years ago committed by GitHub
parent d153fd434a
commit d618bc46d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      conf/defaults.ini
  2. 3
      conf/sample.ini
  3. 5
      docs/sources/setup-grafana/configure-grafana/_index.md
  4. 1
      packages/grafana-runtime/src/config.ts
  5. 33
      pkg/api/dtos/frontend_settings.go
  6. 1
      pkg/api/frontendsettings.go
  7. 11
      pkg/setting/setting.go
  8. 6
      public/app/features/plugins/plugin_loader.ts

@ -378,6 +378,9 @@ angular_support_enabled = true
# The CSRF check will be executed even if the request has no login cookie.
csrf_always_check = false
# Comma-separated list of plugins ids that won't be loaded inside the frontend sandbox
disable_frontend_sandbox_for_plugins =
[security.encryption]
# Defines the time-to-live (TTL) for decrypted data encryption keys stored in memory (cache).
# Please note that small values may cause performance issues due to a high frequency decryption operations.

@ -384,6 +384,9 @@
# The CSRF check will be executed even if the request has no login cookie.
;csrf_always_check = false
# Comma-separated list of plugins ids that won't be loaded inside the frontend sandbox
;disable_frontend_sandbox_for_plugins =
[security.encryption]
# Defines the time-to-live (TTL) for decrypted data encryption keys stored in memory (cache).
# Please note that small values may cause performance issues due to a high frequency decryption operations.

@ -699,6 +699,11 @@ List of allowed headers to be set by the user. Suggested to use for if authentic
Set to `true` to execute the CSRF check even if the login cookie is not in a request (default `false`).
### disable_frontend_sandbox_for_plugins
Comma-separated list of plugins ids that won't be loaded inside the frontend sandbox. It is recommended to only use this
option for plugins that are known to have problems running inside the frontend sandbox.
## [snapshots]
### enabled

@ -162,6 +162,7 @@ export class GrafanaBootConfig implements GrafanaConfig {
};
tokenExpirationDayLimit: undefined;
disableFrontendSandboxForPlugins: string[] = [];
constructor(options: GrafanaBootConfig) {
this.bootData = options.bootData;

@ -159,22 +159,23 @@ type FrontendSettingsDTO struct {
RudderstackSdkUrl string `json:"rudderstackSdkUrl"`
RudderstackConfigUrl string `json:"rudderstackConfigUrl"`
FeedbackLinksEnabled bool `json:"feedbackLinksEnabled"`
ApplicationInsightsConnectionString string `json:"applicationInsightsConnectionString"`
ApplicationInsightsEndpointUrl string `json:"applicationInsightsEndpointUrl"`
DisableLoginForm bool `json:"disableLoginForm"`
DisableUserSignUp bool `json:"disableUserSignUp"`
LoginHint string `json:"loginHint"`
PasswordHint string `json:"passwordHint"`
ExternalUserMngInfo string `json:"externalUserMngInfo"`
ExternalUserMngLinkUrl string `json:"externalUserMngLinkUrl"`
ExternalUserMngLinkName string `json:"externalUserMngLinkName"`
ViewersCanEdit bool `json:"viewersCanEdit"`
AngularSupportEnabled bool `json:"angularSupportEnabled"`
EditorsCanAdmin bool `json:"editorsCanAdmin"`
DisableSanitizeHtml bool `json:"disableSanitizeHtml"`
TrustedTypesDefaultPolicyEnabled bool `json:"trustedTypesDefaultPolicyEnabled"`
CSPReportOnlyEnabled bool `json:"cspReportOnlyEnabled"`
FeedbackLinksEnabled bool `json:"feedbackLinksEnabled"`
ApplicationInsightsConnectionString string `json:"applicationInsightsConnectionString"`
ApplicationInsightsEndpointUrl string `json:"applicationInsightsEndpointUrl"`
DisableLoginForm bool `json:"disableLoginForm"`
DisableUserSignUp bool `json:"disableUserSignUp"`
LoginHint string `json:"loginHint"`
PasswordHint string `json:"passwordHint"`
ExternalUserMngInfo string `json:"externalUserMngInfo"`
ExternalUserMngLinkUrl string `json:"externalUserMngLinkUrl"`
ExternalUserMngLinkName string `json:"externalUserMngLinkName"`
ViewersCanEdit bool `json:"viewersCanEdit"`
AngularSupportEnabled bool `json:"angularSupportEnabled"`
EditorsCanAdmin bool `json:"editorsCanAdmin"`
DisableSanitizeHtml bool `json:"disableSanitizeHtml"`
TrustedTypesDefaultPolicyEnabled bool `json:"trustedTypesDefaultPolicyEnabled"`
CSPReportOnlyEnabled bool `json:"cspReportOnlyEnabled"`
DisableFrontendSandboxForPlugins []string `json:"disableFrontendSandboxForPlugins"`
Auth FrontendSettingsAuthDTO `json:"auth"`

@ -151,6 +151,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
CSPReportOnlyEnabled: hs.Cfg.CSPReportOnlyEnabled,
DateFormats: hs.Cfg.DateFormats,
SecureSocksDSProxyEnabled: hs.Cfg.SecureSocksDSProxy.Enabled && hs.Cfg.SecureSocksDSProxy.ShowUI,
DisableFrontendSandboxForPlugins: hs.Cfg.DisableFrontendSandboxForPlugins,
Auth: dtos.FrontendSettingsAuthDTO{
OAuthSkipOrgRoleUpdateSync: hs.Cfg.OAuthSkipOrgRoleUpdateSync,

@ -226,8 +226,9 @@ type Cfg struct {
// CSPReportEnabled toggles Content Security Policy Report Only support.
CSPReportOnlyEnabled bool
// CSPReportOnlyTemplate contains the Content Security Policy Report Only template.
CSPReportOnlyTemplate string
AngularSupportEnabled bool
CSPReportOnlyTemplate string
AngularSupportEnabled bool
DisableFrontendSandboxForPlugins []string
TempDataLifetime time.Duration
@ -1408,6 +1409,12 @@ func readSecuritySettings(iniFile *ini.File, cfg *Cfg) error {
cfg.CSPReportOnlyEnabled = security.Key("content_security_policy_report_only").MustBool(false)
cfg.CSPReportOnlyTemplate = security.Key("content_security_policy_report_only_template").MustString("")
disableFrontendSandboxForPlugins := security.Key("frontend_sandbox_disable_for_plugins").MustString("")
for _, plug := range strings.Split(disableFrontendSandboxForPlugins, ",") {
plug = strings.TrimSpace(plug)
cfg.DisableFrontendSandboxForPlugins = append(cfg.DisableFrontendSandboxForPlugins, plug)
}
if cfg.CSPEnabled && cfg.CSPTemplate == "" {
return fmt.Errorf("enabling content_security_policy requires a content_security_policy_template configuration")
}

@ -220,20 +220,22 @@ export async function importPluginModule({
}
// the sandboxing environment code cannot work in nodejs and requires a real browser
if (isFrontendSandboxSupported(isAngular)) {
if (isFrontendSandboxSupported({ isAngular, pluginId })) {
return importPluginModuleInSandbox({ pluginId });
}
return grafanaRuntime.SystemJS.import(path);
}
function isFrontendSandboxSupported(isAngular?: boolean): boolean {
function isFrontendSandboxSupported({ isAngular, pluginId }: { isAngular?: boolean; pluginId: string }): boolean {
// To fast test and debug the sandbox in the browser.
const sandboxQueryParam = location.search.includes('nosandbox') && config.buildInfo.env === 'development';
const isPluginExcepted = config.disableFrontendSandboxForPlugins.includes(pluginId);
return (
!isAngular &&
Boolean(config.featureToggles.pluginsFrontendSandbox) &&
process.env.NODE_ENV !== 'test' &&
!isPluginExcepted &&
!sandboxQueryParam
);
}

Loading…
Cancel
Save