fixed charta indexing

This commit is contained in:
2026-03-31 14:40:25 +02:00
parent ec51bf6e34
commit 587ea5ba29
38 changed files with 626 additions and 358 deletions
+1 -1
View File
@@ -20,6 +20,6 @@ import "path/filepath"
type Path string
func (l Path) path(elem ...string) string {
complete := []string{string(l)}
complete := []string{string(l)} //nolint:prealloc
return filepath.Join(append(complete, elem...)...)
}
+23
View File
@@ -296,6 +296,29 @@ func extract(img v1.Image, w io.Writer) error {
// Some tools prepend everything with "./", so if we don't Clean the
// name, we may have duplicate entries, which angers tar-split.
header.Name = filepath.Clean(header.Name)
// Normalize absolute paths to relative to prevent writing outside
// the extraction root (Zip Slip / CVE-2018-15664 class).
// Many OCI tools emit absolute paths; stripping the leading slash
// preserves the entry while removing the danger.
if filepath.IsAbs(header.Name) {
header.Name = strings.TrimLeft(header.Name, "/")
}
// After normalization, reject any remaining path traversal.
if strings.HasPrefix(header.Name, "..") {
continue
}
// Reject symlinks and hardlinks that point outside the extraction
// root. An attacker can create a symlink to /etc and then write
// files through it in a subsequent layer entry.
if header.Typeflag == tar.TypeSymlink || header.Typeflag == tar.TypeLink {
linkTarget := filepath.Clean(header.Linkname)
if strings.HasPrefix(linkTarget, "..") || filepath.IsAbs(linkTarget) {
continue
}
}
// force PAX format to remove Name/Linkname length limit of 100 characters
// required by USTAR and to not depend on internal tar package guess which
// prefers USTAR over PAX
+10 -1
View File
@@ -219,6 +219,15 @@ type tarFile struct {
}
func extractFileFromTar(opener Opener, filePath string) (io.ReadCloser, error) {
return followLinks(opener, filePath, make(map[string]bool))
}
func followLinks(opener Opener, filePath string, visited map[string]bool) (io.ReadCloser, error) {
if visited[filePath] {
return nil, fmt.Errorf("link cycle detected for %s", filePath)
}
visited[filePath] = true
f, err := opener()
if err != nil {
return nil, err
@@ -242,7 +251,7 @@ func extractFileFromTar(opener Opener, filePath string) (io.ReadCloser, error) {
if hdr.Name == filePath {
if hdr.Typeflag == tar.TypeSymlink || hdr.Typeflag == tar.TypeLink {
currentDir := filepath.Dir(filePath)
return extractFileFromTar(opener, path.Join(currentDir, path.Clean(hdr.Linkname)))
return followLinks(opener, path.Join(currentDir, path.Clean(hdr.Linkname)), visited)
}
needClose = false
return tarFile{