Browse Source

Test to check writeComposeFile detects invalid OCI artifact

Signed-off-by: Nicolas De Loof <[email protected]>
(cherry picked from commit 6a90742ef29c392b6626b0ff3f50c6f28f944321)
Signed-off-by: Guillaume Lours <[email protected]>
Nicolas De Loof 2 months ago
parent
commit
47f6d02bef

+ 1 - 1
cmd/formatter/shortcut_windows.go

@@ -22,4 +22,4 @@ package formatter
 func handleCtrlZ() {
 	// Windows doesn't support SIGSTOP/SIGCONT signals
 	// Ctrl+Z behavior is handled differently by the Windows terminal
-}
+}

+ 2 - 2
pkg/compose/publish_test.go

@@ -77,7 +77,8 @@ services:
 			MediaType: "application/vnd.docker.compose.file+yaml",
 			Annotations: map[string]string{
 				"com.docker.compose.file":    "compose.yaml",
-				"com.docker.compose.version": internal.Version},
+				"com.docker.compose.version": internal.Version,
+			},
 		},
 		{
 			MediaType: "application/vnd.docker.compose.file+yaml",
@@ -98,5 +99,4 @@ services:
 	assert.DeepEqual(t, expectedLayers, layers, cmp.FilterPath(func(path cmp.Path) bool {
 		return !slices.Contains([]string{".Data", ".Digest", ".Size"}, path.String())
 	}, cmp.Ignore()))
-
 }

+ 0 - 1
pkg/compose/transform/replace.go

@@ -104,7 +104,6 @@ func ReplaceEnvFile(in []byte, service string, i int, value string) ([]byte, err
 	} else {
 		return replace(in, envFile.Line, envFile.Column, value), nil
 	}
-
 }
 
 func getMapping(root *yaml.Node, key string) (*yaml.Node, error) {

+ 1 - 1
pkg/remote/oci.go

@@ -179,7 +179,7 @@ func (g ociRemoteLoader) Dir(path string) string {
 	return g.known[path]
 }
 
-func (g ociRemoteLoader) pullComposeFiles(ctx context.Context, local string, manifest spec.Manifest, ref reference.Named, resolver remotes.Resolver) error { //nolint:gocyclo
+func (g ociRemoteLoader) pullComposeFiles(ctx context.Context, local string, manifest spec.Manifest, ref reference.Named, resolver remotes.Resolver) error {
 	err := os.MkdirAll(local, 0o700)
 	if err != nil {
 		return err

+ 24 - 10
pkg/remote/oci_test.go

@@ -19,6 +19,9 @@ package remote
 import (
 	"path/filepath"
 	"testing"
+
+	spec "github.com/opencontainers/image-spec/specs-go/v1"
+	"gotest.tools/v3/assert"
 )
 
 func TestValidatePathInBase(t *testing.T) {
@@ -84,11 +87,6 @@ func TestValidatePathInBase(t *testing.T) {
 			unsafePath: "..",
 			wantErr:    true,
 		},
-		{
-			name:       "current directory reference",
-			unsafePath: "./file.yaml",
-			wantErr:    false, // ./ resolves to base dir
-		},
 		{
 			name:       "mixed separators",
 			unsafePath: "config/sub\\file.yaml",
@@ -104,11 +102,6 @@ func TestValidatePathInBase(t *testing.T) {
 			unsafePath: "file-name_v1.2.3.yaml",
 			wantErr:    false,
 		},
-		{
-			name:       "single parent then back",
-			unsafePath: "../compose/file.yaml",
-			wantErr:    false, // Resolves back to base dir, which is fine
-		},
 	}
 
 	for _, tt := range tests {
@@ -123,3 +116,24 @@ func TestValidatePathInBase(t *testing.T) {
 		})
 	}
 }
+
+func TestWriteComposeFileWithExtendsPathTraversal(t *testing.T) {
+	tmpDir := t.TempDir()
+
+	// Create a layer with com.docker.compose.extends=true and a path traversal attempt
+	layer := spec.Descriptor{
+		MediaType: "application/vnd.docker.compose.file.v1+yaml",
+		Digest:    "sha256:test123",
+		Size:      100,
+		Annotations: map[string]string{
+			"com.docker.compose.extends": "true",
+			"com.docker.compose.file":    "../other",
+		},
+	}
+
+	content := []byte("services:\n  test:\n    image: nginx\n")
+
+	// writeComposeFile should return an error due to path traversal
+	err := writeComposeFile(layer, 0, tmpDir, content)
+	assert.Error(t, err, "invalid OCI artifact")
+}