Skip to content
This repository has been archived by the owner on Jan 23, 2025. It is now read-only.

fix(terraform): Use absolute path for filesystem to load tfvars #1271

Merged
merged 2 commits into from
Apr 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions pkg/scanners/terraform/parser/load_vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io/fs"
"os"
"path/filepath"
"runtime"
"strings"

"github.com/hashicorp/hcl/v2"
Expand All @@ -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)

Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
Expand Down
41 changes: 16 additions & 25 deletions pkg/scanners/terraform/parser/load_vars_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
instance_type = "t2.large"
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"variable": {
"foo": {
"default": "bar"
},
"baz": "qux"
},
"foo2": true,
"foo3": 3
}