From b7902c1ae8f602b49633a806346a56abbe7ec054 Mon Sep 17 00:00:00 2001 From: simar7 <1254783+simar7@users.noreply.github.com> Date: Wed, 12 Apr 2023 16:22:37 -0700 Subject: [PATCH] fix(terraform): Use absolute path for filesystem to load tfvars (#1271) * fix(terraform): Use absolute path for filesystem to load tfvars Signed-off-by: Simar * return if already absPath Signed-off-by: Simar --------- Signed-off-by: Simar --- pkg/scanners/terraform/parser/load_vars.go | 33 ++++++++++++--- .../terraform/parser/load_vars_test.go | 41 ++++++++----------- .../parser/testdata/tfvars/terraform.tfvars | 1 + .../testdata/tfvars/terraform.tfvars.json | 10 +++++ 4 files changed, 55 insertions(+), 30 deletions(-) create mode 100644 pkg/scanners/terraform/parser/testdata/tfvars/terraform.tfvars create mode 100644 pkg/scanners/terraform/parser/testdata/tfvars/terraform.tfvars.json diff --git a/pkg/scanners/terraform/parser/load_vars.go b/pkg/scanners/terraform/parser/load_vars.go index 80f9d9bfa..e1009d257 100644 --- a/pkg/scanners/terraform/parser/load_vars.go +++ b/pkg/scanners/terraform/parser/load_vars.go @@ -5,6 +5,7 @@ import ( "io/fs" "os" "path/filepath" + "runtime" "strings" "github.com/hashicorp/hcl/v2" @@ -13,6 +14,23 @@ import ( "github.com/zclconf/go-cty/cty" ) +func getAbsPath(inputPath string) (string, error) { + p, err := filepath.Abs(inputPath) + if err != nil { + return "", fmt.Errorf("unable to determine path: %w", err) + } + switch runtime.GOOS { + case "windows": + if volume := filepath.VolumeName(p); volume != "" { + p = strings.TrimPrefix(filepath.ToSlash(p), volume+"/") + return filepath.FromSlash(p), nil + } + return strings.TrimPrefix(filepath.Clean(p), fmt.Sprintf("%c", os.PathSeparator)), nil + default: + return strings.TrimPrefix(filepath.Clean(p), fmt.Sprintf("%c", os.PathSeparator)), nil + } +} + func loadTFVars(srcFS fs.FS, filenames []string) (map[string]cty.Value, error) { combinedVars := make(map[string]cty.Value) @@ -44,20 +62,25 @@ func loadTFVars(srcFS fs.FS, filenames []string) (map[string]cty.Value, error) { } func loadTFVarsFile(srcFS fs.FS, filename string) (map[string]cty.Value, error) { - inputVars := make(map[string]cty.Value) if filename == "" { return inputVars, nil } - src, err := fs.ReadFile(srcFS, filepath.ToSlash(filename)) + absPath, err := getAbsPath(filename) + if err != nil { + return nil, err + } + absPath = filepath.ToSlash(absPath) // in memory fs is only slash based + + src, err := fs.ReadFile(srcFS, absPath) if err != nil { return nil, err } var attrs hcl.Attributes - if strings.HasSuffix(filename, ".json") { - variableFile, err := hcljson.Parse(src, filename) + if strings.HasSuffix(absPath, ".json") { + variableFile, err := hcljson.Parse(src, absPath) if err != nil { return nil, err } @@ -66,7 +89,7 @@ func loadTFVarsFile(srcFS fs.FS, filename string) (map[string]cty.Value, error) return nil, err } } else { - variableFile, err := hclsyntax.ParseConfig(src, filename, hcl.Pos{Line: 1, Column: 1}) + variableFile, err := hclsyntax.ParseConfig(src, absPath, hcl.Pos{Line: 1, Column: 1}) if err != nil { return nil, err } diff --git a/pkg/scanners/terraform/parser/load_vars_test.go b/pkg/scanners/terraform/parser/load_vars_test.go index e0e9ce9c0..24e86fe10 100644 --- a/pkg/scanners/terraform/parser/load_vars_test.go +++ b/pkg/scanners/terraform/parser/load_vars_test.go @@ -3,35 +3,26 @@ package parser import ( "testing" - "github.com/stretchr/testify/require" - - "github.com/aquasecurity/defsec/test/testutil" + "github.com/zclconf/go-cty/cty" + "github.com/aquasecurity/defsec/pkg/extrafs" "github.com/stretchr/testify/assert" - "github.com/zclconf/go-cty/cty" + "github.com/stretchr/testify/require" ) -func Test_JsonVarsFile(t *testing.T) { - - fs := testutil.CreateFS(t, map[string]string{ - "test.tfvars.json": ` -{ - "variable": { - "foo": { - "default": "bar" - }, - "baz": "qux" - }, - "foo2": true, - "foo3": 3 -} -`, +func Test_TFVarsFile(t *testing.T) { + t.Run("tfvars file", func(t *testing.T) { + vars, err := loadTFVars(extrafs.OSDir("/"), []string{"testdata/tfvars/terraform.tfvars"}) + require.NoError(t, err) + assert.Equal(t, "t2.large", vars["instance_type"].AsString()) }) - vars, err := loadTFVars(fs, []string{"test.tfvars.json"}) - require.NoError(t, err) - assert.Equal(t, "bar", vars["variable"].GetAttr("foo").GetAttr("default").AsString()) - assert.Equal(t, "qux", vars["variable"].GetAttr("baz").AsString()) - assert.Equal(t, true, vars["foo2"].True()) - assert.Equal(t, true, vars["foo3"].Equals(cty.NumberIntVal(3)).True()) + t.Run("tfvars json file", func(t *testing.T) { + vars, err := loadTFVars(extrafs.OSDir("/"), []string{"testdata/tfvars/terraform.tfvars.json"}) + require.NoError(t, err) + assert.Equal(t, "bar", vars["variable"].GetAttr("foo").GetAttr("default").AsString()) + assert.Equal(t, "qux", vars["variable"].GetAttr("baz").AsString()) + assert.Equal(t, true, vars["foo2"].True()) + assert.Equal(t, true, vars["foo3"].Equals(cty.NumberIntVal(3)).True()) + }) } diff --git a/pkg/scanners/terraform/parser/testdata/tfvars/terraform.tfvars b/pkg/scanners/terraform/parser/testdata/tfvars/terraform.tfvars new file mode 100644 index 000000000..23fee69e2 --- /dev/null +++ b/pkg/scanners/terraform/parser/testdata/tfvars/terraform.tfvars @@ -0,0 +1 @@ +instance_type = "t2.large" \ No newline at end of file diff --git a/pkg/scanners/terraform/parser/testdata/tfvars/terraform.tfvars.json b/pkg/scanners/terraform/parser/testdata/tfvars/terraform.tfvars.json new file mode 100644 index 000000000..bde0e7576 --- /dev/null +++ b/pkg/scanners/terraform/parser/testdata/tfvars/terraform.tfvars.json @@ -0,0 +1,10 @@ +{ + "variable": { + "foo": { + "default": "bar" + }, + "baz": "qux" + }, + "foo2": true, + "foo3": 3 +} \ No newline at end of file