fixed charta indexing
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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{
|
||||
|
||||
Reference in New Issue
Block a user