mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-07 19:29:21 +02:00
Introduce DISABLE_INSECURE_FEATURES to disable insecure command executions (#1)
* introduce DISABLE_INSECURE_FEATURES to disable insecure executions Signed-off-by: Quan TRAN <account@itscaro.me> * disable remote sources when DISABLE_INSECURE_FEATURES is set to "true" Signed-off-by: Quan TRAN <account@itscaro.me> * refactor envvar package Signed-off-by: Quan TRAN <account@itscaro.me> * (test) fix test fixtures Signed-off-by: Quan TRAN <account@itscaro.me> * use absolute path to avoid unit test failure Signed-off-by: Quan TRAN <account@itscaro.me> * Fix conflicts Co-authored-by: Yusuke Kuoka <ykuoka@gmail.com>
This commit is contained in:
co-authored by
Yusuke Kuoka
parent
789af92c09
commit
577f54af7a
@@ -8,16 +8,38 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/helmfile/helmfile/pkg/envvar"
|
||||
"github.com/helmfile/helmfile/pkg/helmexec"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
type Values = map[string]interface{}
|
||||
|
||||
var DisableInsecureFeaturesErr = DisableInsecureFeaturesError{envvar.DisableInsecureFeatures + " is active, insecure function calls are disabled"}
|
||||
|
||||
type DisableInsecureFeaturesError struct {
|
||||
err string
|
||||
}
|
||||
|
||||
func (e DisableInsecureFeaturesError) Error() string {
|
||||
return e.err
|
||||
}
|
||||
|
||||
var (
|
||||
disableInsecureFeatures bool
|
||||
skipInsecureTemplateFunctions bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
disableInsecureFeatures, _ = strconv.ParseBool(os.Getenv(envvar.DisableInsecureFeatures))
|
||||
skipInsecureTemplateFunctions, _ = strconv.ParseBool(os.Getenv(envvar.SkipInsecureTemplateFunctions))
|
||||
}
|
||||
|
||||
func (c *Context) createFuncMap() template.FuncMap {
|
||||
funcMap := template.FuncMap{
|
||||
"envExec": c.EnvExec,
|
||||
@@ -36,7 +58,7 @@ func (c *Context) createFuncMap() template.FuncMap {
|
||||
"fetchSecretValue": fetchSecretValue,
|
||||
"expandSecretRefs": fetchSecretValues,
|
||||
}
|
||||
if c.preRender {
|
||||
if c.preRender || skipInsecureTemplateFunctions {
|
||||
// disable potential side-effect template calls
|
||||
funcMap["exec"] = func(string, []interface{}, ...string) (string, error) {
|
||||
return "", nil
|
||||
@@ -48,6 +70,15 @@ func (c *Context) createFuncMap() template.FuncMap {
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
if disableInsecureFeatures {
|
||||
// disable insecure functions
|
||||
funcMap["exec"] = func(string, []interface{}, ...string) (string, error) {
|
||||
return "", DisableInsecureFeaturesErr
|
||||
}
|
||||
funcMap["readFile"] = func(string) (string, error) {
|
||||
return "", DisableInsecureFeaturesErr
|
||||
}
|
||||
}
|
||||
|
||||
return funcMap
|
||||
}
|
||||
|
||||
@@ -12,6 +12,57 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCreateFuncMap(t *testing.T) {
|
||||
currentVal := disableInsecureFeatures
|
||||
|
||||
{
|
||||
disableInsecureFeatures = false
|
||||
ctx := &Context{basePath: "."}
|
||||
funcMaps := ctx.createFuncMap()
|
||||
args := make([]interface{}, 0)
|
||||
outputExec, _ := funcMaps["exec"].(func(command string, args []interface{}, inputs ...string) (string, error))("ls", args)
|
||||
require.Contains(t, outputExec, "context.go")
|
||||
}
|
||||
|
||||
disableInsecureFeatures = currentVal
|
||||
}
|
||||
|
||||
func TestCreateFuncMap_DisabledInsecureFeatures(t *testing.T) {
|
||||
currentVal := disableInsecureFeatures
|
||||
|
||||
{
|
||||
disableInsecureFeatures = true
|
||||
ctx := &Context{basePath: "."}
|
||||
funcMaps := ctx.createFuncMap()
|
||||
args := make([]interface{}, 0)
|
||||
_, err1 := funcMaps["exec"].(func(command string, args []interface{}, inputs ...string) (string, error))("ls", args)
|
||||
require.ErrorIs(t, err1, DisableInsecureFeaturesErr)
|
||||
_, err2 := funcMaps["readFile"].(func(filename string) (string, error))("context_funcs_test.go")
|
||||
require.ErrorIs(t, err2, DisableInsecureFeaturesErr)
|
||||
}
|
||||
|
||||
disableInsecureFeatures = currentVal
|
||||
}
|
||||
|
||||
func TestCreateFuncMap_SkipInsecureTemplateFunctions(t *testing.T) {
|
||||
currentVal := skipInsecureTemplateFunctions
|
||||
|
||||
{
|
||||
skipInsecureTemplateFunctions = true
|
||||
ctx := &Context{basePath: "."}
|
||||
funcMaps := ctx.createFuncMap()
|
||||
args := make([]interface{}, 0)
|
||||
actual1, err1 := funcMaps["exec"].(func(command string, args []interface{}, inputs ...string) (string, error))("ls", args)
|
||||
require.Equal(t, "", actual1)
|
||||
require.ErrorIs(t, err1, nil)
|
||||
actual2, err2 := funcMaps["readFile"].(func(filename string) (string, error))("context_funcs_test.go")
|
||||
require.Equal(t, "", actual2)
|
||||
require.ErrorIs(t, err2, nil)
|
||||
}
|
||||
|
||||
skipInsecureTemplateFunctions = currentVal
|
||||
}
|
||||
|
||||
func TestReadFile(t *testing.T) {
|
||||
expected := `foo:
|
||||
bar: BAR
|
||||
|
||||
Reference in New Issue
Block a user