From e878f2a3e730a1f6aa06a72ac3d0ae952db21183 Mon Sep 17 00:00:00 2001 From: viniciusdc Date: Sun, 24 May 2026 00:05:57 -0300 Subject: [PATCH] chore(test): tighten path handling in test utilities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two small hygiene fixes in test/utils/utils.go: - LoadTestDataFile now constrains its `filename` argument to stay inside test/e2e/testdata/. Previously the path was built by raw string concat — a caller passing a name with `..` would have escaped the testdata directory. Now it uses filepath.Join + filepath.Rel and rejects anything that traverses out. - UncommentCode writes its output file with mode 0600 (was 0644). Test fixtures don't need group/other readability; the existing nolint:gosec suppression was a workaround for the lint rule. Test-utility code only. No operator runtime impact. Build + lint clean; the test/utils package has no test files so there's nothing new to run against. --- test/utils/utils.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/utils/utils.go b/test/utils/utils.go index 7122974..f8cde8b 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -22,6 +22,7 @@ import ( "fmt" "os" "os/exec" + "path/filepath" "sort" "strings" @@ -246,13 +247,21 @@ func GetNonEmptyLines(output string) []string { // LoadTestDataFile reads a YAML file from the testdata directory and replaces placeholders. // The replacements map contains key-value pairs where keys are placeholders to be replaced // with their corresponding values. +// +// filename is constrained to stay within test/e2e/testdata/ — `..` traversal is rejected. func LoadTestDataFile(filename string, replacements map[string]string) (string, error) { projectDir, err := GetProjectDir() if err != nil { return "", fmt.Errorf("failed to get project directory: %w", err) } - filePath := fmt.Sprintf("%s/test/e2e/testdata/%s", projectDir, filename) + testdataDir := filepath.Join(projectDir, "test", "e2e", "testdata") + filePath := filepath.Clean(filepath.Join(testdataDir, filename)) + rel, err := filepath.Rel(testdataDir, filePath) + if err != nil || strings.HasPrefix(rel, "..") || strings.Contains(rel, string(filepath.Separator)+"..") { + return "", fmt.Errorf("invalid filename %q: must be inside test/e2e/testdata/", filename) + } + content, err := os.ReadFile(filePath) if err != nil { return "", fmt.Errorf("failed to read file %s: %w", filePath, err) @@ -330,9 +339,7 @@ func UncommentCode(filename, target, prefix string) error { return fmt.Errorf("failed to write to output: %w", err) } - // false positive - // nolint:gosec - if err = os.WriteFile(filename, out.Bytes(), 0644); err != nil { + if err = os.WriteFile(filename, out.Bytes(), 0600); err != nil { return fmt.Errorf("failed to write file %q: %w", filename, err) }