@@ -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