From d28afdab5a2c448dcbfc4e6e661dccbbfb0bd683 Mon Sep 17 00:00:00 2001 From: James Humphries Date: Tue, 23 Jul 2024 14:24:36 +0100 Subject: [PATCH] [Backport #1801] Sensitive path usage in templatefile shouldn't panic (#1846) Signed-off-by: James Humphries --- CHANGELOG.md | 2 +- internal/lang/funcs/filesystem.go | 11 ++++++----- internal/lang/funcs/filesystem_test.go | 22 ++++++++++++++++++++-- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba24ae27af..bd3c7d939d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,7 +34,7 @@ BUG FIXES: * Fixed issue with migration between versions can cause an update in-place for resources when no changes are needed. ([#1640](https://github.com/opentofu/opentofu/pull/1640)) * Add source context for the 'insufficient feature blocks' error ([#1777](https://github.com/opentofu/opentofu/pull/1777)) * Remove encryption diags from autocomplete ([#1793](https://github.com/opentofu/opentofu/pull/1793)) - +* Ensure that using a sensitive path for templatefile that it doesn't panic([#1801](https://github.com/opentofu/opentofu/issues/1801)) ## Previous Releases diff --git a/internal/lang/funcs/filesystem.go b/internal/lang/funcs/filesystem.go index 25b6f62b5b..3e55c11726 100644 --- a/internal/lang/funcs/filesystem.go +++ b/internal/lang/funcs/filesystem.go @@ -121,7 +121,6 @@ func MakeTemplateFileFunc(baseDir string, funcsCb func() map[string]function.Fun return makeTemplateFileFuncImpl(baseDir, funcsCb, 0) } func makeTemplateFileFuncImpl(baseDir string, funcsCb func() map[string]function.Function, depth int) function.Function { - params := []function.Parameter{ { Name: "path", @@ -134,7 +133,7 @@ func makeTemplateFileFuncImpl(baseDir string, funcsCb func() map[string]function }, } - loadTmpl := func(fn string, marks cty.ValueMarks) (hcl.Expression, error) { + loadTmpl := func(path string, marks cty.ValueMarks) (hcl.Expression, error) { maxDepth, err := templateMaxRecursionDepth() if err != nil { return nil, err @@ -146,12 +145,15 @@ func makeTemplateFileFuncImpl(baseDir string, funcsCb func() map[string]function // We re-use File here to ensure the same filename interpretation // as it does, along with its other safety checks. - tmplVal, err := File(baseDir, cty.StringVal(fn).WithMarks(marks)) + templateValue, err := File(baseDir, cty.StringVal(path).WithMarks(marks)) if err != nil { return nil, err } - expr, diags := hclsyntax.ParseTemplate([]byte(tmplVal.AsString()), fn, hcl.Pos{Line: 1, Column: 1}) + // unmark the template ready to be handled + templateValue, _ = templateValue.Unmark() + + expr, diags := hclsyntax.ParseTemplate([]byte(templateValue.AsString()), path, hcl.Pos{Line: 1, Column: 1}) if diags.HasErrors() { return nil, diags } @@ -206,7 +208,6 @@ func makeTemplateFileFuncImpl(baseDir string, funcsCb func() map[string]function return result.WithMarks(pathMarks), err }, }) - } // MakeFileExistsFunc constructs a function that takes a path diff --git a/internal/lang/funcs/filesystem_test.go b/internal/lang/funcs/filesystem_test.go index addb9b74a2..a64da91e3b 100644 --- a/internal/lang/funcs/filesystem_test.go +++ b/internal/lang/funcs/filesystem_test.go @@ -6,16 +6,18 @@ package funcs import ( + "errors" "fmt" "os" "path/filepath" "testing" homedir "github.com/mitchellh/go-homedir" - "github.com/opentofu/opentofu/internal/lang/marks" "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/function" "github.com/zclconf/go-cty/cty/function/stdlib" + + "github.com/opentofu/opentofu/internal/lang/marks" ) func TestFile(t *testing.T) { @@ -181,6 +183,21 @@ func TestTemplateFile(t *testing.T) { cty.True, // since this template contains only an interpolation, its true value shines through ``, }, + { + // write to a sensitive file path that exists + cty.StringVal("testdata/hello.txt").Mark(marks.Sensitive), + cty.EmptyObjectVal, + cty.StringVal("Hello World").Mark(marks.Sensitive), + ``, + }, + { + cty.StringVal("testdata/bare.tmpl"), + cty.ObjectVal(map[string]cty.Value{ + "val": cty.True.Mark(marks.Sensitive), + }), + cty.True.Mark(marks.Sensitive), + ``, + }, } templateFileFn := MakeTemplateFileFunc(".", func() map[string]function.Function { @@ -194,7 +211,8 @@ func TestTemplateFile(t *testing.T) { t.Run(fmt.Sprintf("TemplateFile(%#v, %#v)", test.Path, test.Vars), func(t *testing.T) { got, err := templateFileFn.Call([]cty.Value{test.Path, test.Vars}) - if argErr, ok := err.(function.ArgError); ok { + var argErr function.ArgError + if errors.As(err, &argErr) { if argErr.Index < 0 || argErr.Index > 1 { t.Errorf("ArgError index %d is out of range for templatefile (must be 0 or 1)", argErr.Index) }