Skip to content

Commit 310bab2

Browse files
committed
fix path risk
1 parent bdbb5b2 commit 310bab2

1 file changed

Lines changed: 15 additions & 11 deletions

File tree

tools/trond/utils/http.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -501,28 +501,32 @@ func ExtractTgzWithStatus(tgzFile, destDir string) error {
501501
// Increment the file count
502502
totalFilesExtracted++
503503
case tar.TypeSymlink:
504+
// Resolve the symlink target
505+
resolvedLinkname, err := filepath.EvalSymlinks(filepath.Join(filepath.Dir(target), header.Linkname))
506+
if err != nil {
507+
return fmt.Errorf("failed to resolve symlink target: %v", err)
508+
}
504509
// Sanitize symlink target to prevent directory traversal
505-
sanitizedLinkname := filepath.Clean(header.Linkname)
506-
if strings.HasPrefix(sanitizedLinkname, "/") || strings.Contains(sanitizedLinkname, "..") {
510+
if !strings.HasPrefix(filepath.Clean(resolvedLinkname), filepath.Clean(destDir)+string(os.PathSeparator)) {
507511
return fmt.Errorf("invalid symlink target in archive: %s -> %s", header.Name, header.Linkname)
508512
}
509513

510-
// Ensure the resolved symlink target stays within the destination directory
511-
fullTarget := filepath.Join(filepath.Dir(target), sanitizedLinkname)
512-
if !strings.HasPrefix(filepath.Clean(fullTarget), filepath.Clean(destDir)+string(os.PathSeparator)) {
513-
return fmt.Errorf("attempted directory traversal in symlink: %s -> %s", header.Name, header.Linkname)
514-
}
515-
516514
// Create symlink
517-
if err := os.Symlink(header.Linkname, target); err != nil {
515+
if err := os.Symlink(resolvedLinkname, target); err != nil {
518516
return fmt.Errorf("failed to create symlink: %v", err)
519517
}
520518
case tar.TypeLink:
521519
// Create hard link
522520
linkTarget := filepath.Join(destDir, header.Linkname)
523521
// Sanitize the link target to prevent directory traversal
524-
sanitizedLinkTarget := filepath.Clean(linkTarget)
525-
if !strings.HasPrefix(sanitizedLinkTarget, filepath.Clean(destDir)+string(os.PathSeparator)) {
522+
// Resolve the hard link target
523+
resolvedLinkTarget, err := filepath.EvalSymlinks(linkTarget)
524+
if err != nil {
525+
return fmt.Errorf("failed to resolve hard link target: %v", err)
526+
}
527+
528+
// Ensure the resolved hard link target stays within the destination directory
529+
if !strings.HasPrefix(filepath.Clean(resolvedLinkTarget), filepath.Clean(destDir)+string(os.PathSeparator)) {
526530
return fmt.Errorf("attempted directory traversal in hard link: %s -> %s", header.Name, header.Linkname)
527531
}
528532

0 commit comments

Comments
 (0)