Plugins: Prevent passing host environment variables to plugin processes by default (#113412)

* remove pluginsSkipHostEnvVars toggle

* fix tests
This commit is contained in:
Will Browne
2025-11-13 15:31:57 +00:00
committed by GitHub
parent ae8a8cf16e
commit f041563df3
11 changed files with 188 additions and 212 deletions
-1
View File
@@ -28,7 +28,6 @@ type PluginManagementCfg struct {
// Features contains the feature toggles used for the plugin management system.
type Features struct {
SkipHostEnvVarsEnabled bool
SriChecksEnabled bool
LocalizationForPlugins bool
// Needed only until Tempo Alerting / metrics TraceQL is stable
+38 -33
View File
@@ -122,12 +122,13 @@ func TestLoader_Load(t *testing.T) {
Backend: true,
QueryOptions: map[string]bool{"minInterval": true},
},
Module: "core:plugin/cloudwatch",
BaseURL: "public/plugins/cloudwatch",
FS: mustNewStaticFSForTests(t, filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")),
Signature: plugins.SignatureStatusInternal,
Class: plugins.ClassCore,
Translations: map[string]string{},
Module: "core:plugin/cloudwatch",
BaseURL: "public/plugins/cloudwatch",
FS: mustNewStaticFSForTests(t, filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")),
Signature: plugins.SignatureStatusInternal,
Class: plugins.ClassCore,
SkipHostEnvVars: true,
Translations: map[string]string{},
},
},
},
@@ -215,14 +216,15 @@ func TestLoader_Load(t *testing.T) {
ExtensionPoints: []plugins.ExtensionPoint{},
},
},
Class: plugins.ClassExternal,
Module: "public/plugins/test-app/module.js",
BaseURL: "public/plugins/test-app",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/includes-symlinks")),
Signature: "valid",
SignatureType: plugins.SignatureTypeGrafana,
SignatureOrg: "Grafana Labs",
Translations: map[string]string{},
Class: plugins.ClassExternal,
Module: "public/plugins/test-app/module.js",
BaseURL: "public/plugins/test-app",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/includes-symlinks")),
Signature: "valid",
SignatureType: plugins.SignatureTypeGrafana,
SignatureOrg: "Grafana Labs",
SkipHostEnvVars: true,
Translations: map[string]string{},
},
},
},
@@ -268,12 +270,13 @@ func TestLoader_Load(t *testing.T) {
Backend: true,
State: plugins.ReleaseStateAlpha,
},
Class: plugins.ClassExternal,
Module: "public/plugins/test-datasource/module.js",
BaseURL: "public/plugins/test-datasource",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")),
Signature: "unsigned",
Translations: map[string]string{},
Class: plugins.ClassExternal,
Module: "public/plugins/test-datasource/module.js",
BaseURL: "public/plugins/test-datasource",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")),
Signature: "unsigned",
SkipHostEnvVars: true,
Translations: map[string]string{},
},
},
},
@@ -326,12 +329,13 @@ func TestLoader_Load(t *testing.T) {
Backend: true,
State: plugins.ReleaseStateAlpha,
},
Class: plugins.ClassExternal,
Module: "public/plugins/test-datasource/module.js",
BaseURL: "public/plugins/test-datasource",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")),
Signature: plugins.SignatureStatusUnsigned,
Translations: map[string]string{},
Class: plugins.ClassExternal,
Module: "public/plugins/test-datasource/module.js",
BaseURL: "public/plugins/test-datasource",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")),
Signature: plugins.SignatureStatusUnsigned,
SkipHostEnvVars: true,
Translations: map[string]string{},
},
},
},
@@ -422,13 +426,14 @@ func TestLoader_Load(t *testing.T) {
},
Backend: false,
},
DefaultNavURL: "/plugins/test-app/page/root-page-react",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/test-app-with-includes")),
Class: plugins.ClassExternal,
Signature: plugins.SignatureStatusUnsigned,
Module: "public/plugins/test-app/module.js",
BaseURL: "public/plugins/test-app",
Translations: map[string]string{},
DefaultNavURL: "/plugins/test-app/page/root-page-react",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/test-app-with-includes")),
Class: plugins.ClassExternal,
Signature: plugins.SignatureStatusUnsigned,
Module: "public/plugins/test-app/module.js",
BaseURL: "public/plugins/test-app",
SkipHostEnvVars: true,
Translations: map[string]string{},
},
},
},
@@ -137,11 +137,10 @@ func configureAppChildPlugin(parent *plugins.Plugin, child *plugins.Plugin) {
}
// SkipHostEnvVarsDecorateFunc returns a DecorateFunc that configures the SkipHostEnvVars field of the plugin.
// It will be set to true if the FlagPluginsSkipHostEnvVars feature flag is set, and the plugin is not present in the
// ForwardHostEnvVars plugin ids list.
// It will be set to true if the plugin is not present in the ForwardHostEnvVars plugin ids list.
func SkipHostEnvVarsDecorateFunc(cfg *config.PluginManagementCfg) DecorateFunc {
return func(_ context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
p.SkipHostEnvVars = cfg.Features.SkipHostEnvVarsEnabled && !slices.Contains(cfg.ForwardHostEnvVars, p.ID)
p.SkipHostEnvVars = !slices.Contains(cfg.ForwardHostEnvVars, p.ID)
return p, nil
}
}
@@ -144,65 +144,39 @@ func Test_configureAppChildPlugin(t *testing.T) {
func TestSkipEnvVarsDecorateFunc(t *testing.T) {
const pluginID = "plugin-id"
t.Run("config field is false", func(t *testing.T) {
f := SkipHostEnvVarsDecorateFunc(&config.PluginManagementCfg{
Features: config.Features{SkipHostEnvVarsEnabled: false},
})
p, err := f(context.Background(), &plugins.Plugin{JSONData: plugins.JSONData{ID: pluginID}})
require.NoError(t, err)
require.False(t, p.SkipHostEnvVars)
})
t.Run("config field is true", func(t *testing.T) {
t.Run("no plugin settings should set SkipHostEnvVars to true", func(t *testing.T) {
for _, tc := range []struct {
name string
forwardHostEnvVars []string
expSkipHostEnvVars bool
}{
{
name: "plugin id not present in forwardHostEnvVars should set SkipHostEnvVars to true (empty)",
forwardHostEnvVars: []string{},
expSkipHostEnvVars: true,
},
{
name: "plugin id not present in forwardHostEnvVars should set SkipHostEnvVars to true (other id)",
forwardHostEnvVars: []string{"other-id", "yet-another-id"},
expSkipHostEnvVars: true,
},
{
name: "plugin id in forwardHostEnvVars should set SkipHostEnvVars to false (only)",
forwardHostEnvVars: []string{pluginID},
expSkipHostEnvVars: false,
},
{
name: "plugin id in forwardHostEnvVars should set SkipHostEnvVars to false (with other)",
forwardHostEnvVars: []string{"a-plugin", pluginID, "other-id"},
expSkipHostEnvVars: false,
},
} {
t.Run(tc.name, func(t *testing.T) {
f := SkipHostEnvVarsDecorateFunc(&config.PluginManagementCfg{
Features: config.Features{SkipHostEnvVarsEnabled: true},
ForwardHostEnvVars: tc.forwardHostEnvVars,
})
p, err := f(context.Background(), &plugins.Plugin{JSONData: plugins.JSONData{ID: pluginID}})
require.NoError(t, err)
require.True(t, p.SkipHostEnvVars)
require.Equal(t, tc.expSkipHostEnvVars, p.SkipHostEnvVars)
})
t.Run("plugin setting", func(t *testing.T) {
for _, tc := range []struct {
name string
forwardHostEnvVars []string
expSkipHostEnvVars bool
}{
{
name: "plugin id not present in forwardHostEnvVars should set SkipHostEnvVars to true (empty)",
forwardHostEnvVars: []string{},
expSkipHostEnvVars: true,
},
{
name: "plugin id not present in forwardHostEnvVars should set SkipHostEnvVars to true (other id)",
forwardHostEnvVars: []string{"other-id", "yet-another-id"},
expSkipHostEnvVars: true,
},
{
name: "plugin id in forwardHostEnvVars should set SkipHostEnvVars to false (only)",
forwardHostEnvVars: []string{pluginID},
expSkipHostEnvVars: false,
},
{
name: "plugin id in forwardHostEnvVars should set SkipHostEnvVars to false (with other)",
forwardHostEnvVars: []string{"a-plugin", pluginID, "other-id"},
expSkipHostEnvVars: false,
},
} {
t.Run(tc.name, func(t *testing.T) {
f := SkipHostEnvVarsDecorateFunc(&config.PluginManagementCfg{
Features: config.Features{
SkipHostEnvVarsEnabled: true,
},
ForwardHostEnvVars: tc.forwardHostEnvVars,
})
p, err := f(context.Background(), &plugins.Plugin{JSONData: plugins.JSONData{ID: pluginID}})
require.NoError(t, err)
require.Equal(t, tc.expSkipHostEnvVars, p.SkipHostEnvVars)
})
}
})
})
}
}