mirror of
https://github.com/anchore/syft.git
synced 2026-10-30 14:02:26 +01:00
Decoding SPDX, CycloneDX and syft-json rebuilt nested archive chains from whatever the document said, with no checks on entry names, depth or length. A small crafted document could forge archive boundaries or cost memory quadratic in its size (a 3 MB SPDX allocated ~14 GB). - decoders now hold names to the scan's `EntryName` rules, and chains to `MaxDepth` (16) and PATH_MAX in length - a file within a refused chain is dropped, rather than moved to a top-level path or merged into its outer archive - the scan holds itself to the same bounds, so its SBOMs always decode back: a configured `nested-archive-max-depth` past 16 stops at 16, and an entry whose chain would be too long is skipped and the archive reported as truncated Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
46 lines
1.3 KiB
Go
46 lines
1.3 KiB
Go
package internal
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/anchore/syft/internal/archive"
|
|
"github.com/anchore/syft/syft/file"
|
|
)
|
|
|
|
func TestNestedCoordinates(t *testing.T) {
|
|
war := file.NewCoordinates("/app.war", "layer")
|
|
|
|
got, ok := NestedCoordinates(war, "/WEB-INF/lib/a.jar")
|
|
require.True(t, ok)
|
|
assert.Equal(t, file.Coordinates{RealPath: "/app.war", FileSystemID: "layer", FullPath: "/app.war!/WEB-INF/lib/a.jar"}, got)
|
|
|
|
for _, name := range []string{"", "/", "a.jar!/BOOT-INF/lib/b.jar", "a\nb", strings.Repeat("a", 4097)} {
|
|
_, ok := NestedCoordinates(war, name)
|
|
assert.False(t, ok, "%q", name)
|
|
}
|
|
|
|
// nesting stops as deep as a scan goes
|
|
c := war
|
|
for range archive.MaxDepth {
|
|
c, ok = NestedCoordinates(c, "a.jar")
|
|
require.True(t, ok)
|
|
}
|
|
_, ok = NestedCoordinates(c, "a.jar")
|
|
assert.False(t, ok)
|
|
|
|
// so does a chain longer than a path, however it gets there: a long container name shared by many entries
|
|
// would otherwise cost memory quadratic in the document
|
|
long := file.NewCoordinates("/"+strings.Repeat("a", archive.MaxPathBytes), "layer")
|
|
_, ok = NestedCoordinates(long, "a.jar")
|
|
assert.False(t, ok)
|
|
c = war
|
|
for range 3 {
|
|
c, ok = NestedCoordinates(c, strings.Repeat("a", 2000))
|
|
}
|
|
assert.False(t, ok)
|
|
}
|