From d3fefd96da00c1070ba4f3da68815a28bcde0557 Mon Sep 17 00:00:00 2001 From: Simar Date: Fri, 7 Apr 2023 21:42:31 -0700 Subject: [PATCH 1/2] fix(terraform): Use absolute path for filesystem to load tfvars Signed-off-by: Simar --- pkg/scanners/terraform/parser/load_vars.go | 32 +++++++++++--- .../terraform/parser/load_vars_test.go | 44 +++++++++---------- .../parser/testdata/tfvars/terraform.tfvars | 1 + .../testdata/tfvars/terraform.tfvars.json | 10 +++++ 4 files changed, 58 insertions(+), 29 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..40f67abc8 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(path string) (string, error) { + p, err := filepath.Abs(path) + 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,24 @@ 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 + } + + 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 +88,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..ed25b964b 100644 --- a/pkg/scanners/terraform/parser/load_vars_test.go +++ b/pkg/scanners/terraform/parser/load_vars_test.go @@ -3,35 +3,31 @@ package parser import ( "testing" - "github.com/stretchr/testify/require" - - "github.com/aquasecurity/defsec/test/testutil" - + "github.com/aquasecurity/defsec/pkg/extrafs" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/zclconf/go-cty/cty" ) -func Test_JsonVarsFile(t *testing.T) { +func Test_TFVarsFile(t *testing.T) { + t.Run("tfvars file", func(t *testing.T) { + absPath, err := getAbsPath("testdata/tfvars/terraform.tfvars") + require.NoError(t, err) - fs := testutil.CreateFS(t, map[string]string{ - "test.tfvars.json": ` -{ - "variable": { - "foo": { - "default": "bar" - }, - "baz": "qux" - }, - "foo2": true, - "foo3": 3 -} -`, + vars, err := loadTFVars(extrafs.OSDir("/"), []string{absPath}) + 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) { + absPath, err := getAbsPath("testdata/tfvars/terraform.tfvars.json") + require.NoError(t, err) + + vars, err := loadTFVars(extrafs.OSDir("/"), []string{absPath}) + 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 From 13ae875a54cbc1d51dfa319c5ae42567374eebc0 Mon Sep 17 00:00:00 2001 From: Simar Date: Mon, 10 Apr 2023 10:50:05 -0700 Subject: [PATCH 2/2] return if already absPath Signed-off-by: Simar --- pkg/scanners/terraform/parser/load_vars.go | 5 +++-- pkg/scanners/terraform/parser/load_vars_test.go | 13 ++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/pkg/scanners/terraform/parser/load_vars.go b/pkg/scanners/terraform/parser/load_vars.go index 40f67abc8..e1009d257 100644 --- a/pkg/scanners/terraform/parser/load_vars.go +++ b/pkg/scanners/terraform/parser/load_vars.go @@ -14,8 +14,8 @@ import ( "github.com/zclconf/go-cty/cty" ) -func getAbsPath(path string) (string, error) { - p, err := filepath.Abs(path) +func getAbsPath(inputPath string) (string, error) { + p, err := filepath.Abs(inputPath) if err != nil { return "", fmt.Errorf("unable to determine path: %w", err) } @@ -71,6 +71,7 @@ func loadTFVarsFile(srcFS fs.FS, filename string) (map[string]cty.Value, error) 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 { diff --git a/pkg/scanners/terraform/parser/load_vars_test.go b/pkg/scanners/terraform/parser/load_vars_test.go index ed25b964b..24e86fe10 100644 --- a/pkg/scanners/terraform/parser/load_vars_test.go +++ b/pkg/scanners/terraform/parser/load_vars_test.go @@ -3,27 +3,22 @@ package parser import ( "testing" + "github.com/zclconf/go-cty/cty" + "github.com/aquasecurity/defsec/pkg/extrafs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/zclconf/go-cty/cty" ) func Test_TFVarsFile(t *testing.T) { t.Run("tfvars file", func(t *testing.T) { - absPath, err := getAbsPath("testdata/tfvars/terraform.tfvars") - require.NoError(t, err) - - vars, err := loadTFVars(extrafs.OSDir("/"), []string{absPath}) + vars, err := loadTFVars(extrafs.OSDir("/"), []string{"testdata/tfvars/terraform.tfvars"}) require.NoError(t, err) assert.Equal(t, "t2.large", vars["instance_type"].AsString()) }) t.Run("tfvars json file", func(t *testing.T) { - absPath, err := getAbsPath("testdata/tfvars/terraform.tfvars.json") - require.NoError(t, err) - - vars, err := loadTFVars(extrafs.OSDir("/"), []string{absPath}) + 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())