diff --git a/commitserver/commit/default_mkdir_provider.go b/commitserver/commit/default_mkdir_provider.go new file mode 100644 index 0000000000000..075ac9a48db6a --- /dev/null +++ b/commitserver/commit/default_mkdir_provider.go @@ -0,0 +1,22 @@ +//go:build !linux + +package commit + +import ( + "fmt" + "os" + + securejoin "github.com/cyphar/filepath-securejoin" +) + +func SecureMkdirAll(root, unsafePath string, mode os.FileMode) (string, error) { + fullPath, err := securejoin.SecureJoin(root, unsafePath) + if err != nil { + return "", fmt.Errorf("failed to construct secure path: %w", err) + } + err = os.MkdirAll(fullPath, mode) + if err != nil { + return "", fmt.Errorf("failed to create directory: %w", err) + } + return fullPath, nil +} diff --git a/commitserver/commit/default_mkdir_provider_test.go b/commitserver/commit/default_mkdir_provider_test.go new file mode 100644 index 0000000000000..1d3587405030e --- /dev/null +++ b/commitserver/commit/default_mkdir_provider_test.go @@ -0,0 +1,23 @@ +//go:build !linux + +package commit + +import ( + "os" + "path" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSecureMkdirAllDefault(t *testing.T) { + root := t.TempDir() + + unsafePath := "test/dir" + fullPath, err := SecureMkdirAll(root, unsafePath, os.ModePerm) + require.NoError(t, err) + + expectedPath := path.Join(root, unsafePath) + assert.Equal(t, expectedPath, fullPath) +} diff --git a/commitserver/commit/hydratorhelper.go b/commitserver/commit/hydratorhelper.go index f9856f61d7921..1770aaba908c3 100644 --- a/commitserver/commit/hydratorhelper.go +++ b/commitserver/commit/hydratorhelper.go @@ -8,7 +8,6 @@ import ( "path" "text/template" - securejoin "github.com/cyphar/filepath-securejoin" log "github.com/sirupsen/logrus" "gopkg.in/yaml.v3" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -30,13 +29,9 @@ func WriteForPaths(rootPath string, repoUrl string, drySha string, paths []*apic if hydratePath == "." { hydratePath = "" } + var fullHydratePath string - fullHydratePath, err = securejoin.SecureJoin(rootPath, hydratePath) - if err != nil { - return fmt.Errorf("failed to construct hydrate path: %w", err) - } - // TODO: consider switching to securejoin.MkdirAll: https://github.com/cyphar/filepath-securejoin?tab=readme-ov-file#mkdirall - err = os.MkdirAll(fullHydratePath, os.ModePerm) + fullHydratePath, err = SecureMkdirAll(rootPath, hydratePath, os.ModePerm) if err != nil { return fmt.Errorf("failed to create path: %w", err) } diff --git a/commitserver/commit/linux_mkdir_provider.go b/commitserver/commit/linux_mkdir_provider.go new file mode 100644 index 0000000000000..79167ce031bf5 --- /dev/null +++ b/commitserver/commit/linux_mkdir_provider.go @@ -0,0 +1,21 @@ +//go:build linux + +package commit + +import ( + "fmt" + + "github.com/cyphar/filepath-securejoin" +) + +func SecureMkdirAll(root, unsafePath string, mode os.FileMode) (string, error) { + err := securejoin.MkdirAll(root, unsafePath, mode) + if err != nil { + return "", fmt.Errorf("failed to make directory: %w", err) + } + fullPath, err := securejoin.SecureJoin(root, unsafePath) + if err != nil { + return "", fmt.Errorf("failed to construct secure path: %w", err) + } + return fullPath, nil +} diff --git a/commitserver/commit/linux_mkdir_provider_test.go b/commitserver/commit/linux_mkdir_provider_test.go new file mode 100644 index 0000000000000..025addec589c7 --- /dev/null +++ b/commitserver/commit/linux_mkdir_provider_test.go @@ -0,0 +1,21 @@ +//go:build linux + +package commit + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSecureMkdirAllLinux(t *testing.T) { + root := t.TempDir() + + unsafePath := "test/dir" + fullPath, err := SecureMkdirAll(root, unsafePath, os.ModePerm) + require.NoError(t, err) + + expectedPath := path.Join(root, unsafePath) + require.Equal(t, expectedPath, fullPath) +}