77 "io"
88 "os"
99 "path/filepath"
10+ "strings"
1011)
1112
1213// Untar writes a tar stream to a filesystem.
@@ -22,15 +23,24 @@ func Untar(in io.Reader, dir string) error {
2223 return err
2324 }
2425
25- abs := filepath .Join (dir , header .Name ) //nolint:gosec // tar
26+ fp , err := sanitizeArchivePath (dir , header .Name )
27+ if err != nil {
28+ return fmt .Errorf ("illegal file path: %s" , header .Name )
29+ }
30+
31+ abs := filepath .Join (dir , fp )
2632
2733 switch header .Typeflag {
2834 case tar .TypeDir :
2935 if err := os .MkdirAll (abs , os .FileMode (header .Mode )); err != nil {
3036 return fmt .Errorf ("unable to create directory %s: %w" , header .Name , err )
3137 }
3238 case tar .TypeReg :
33- file , err := os .OpenFile (abs , os .O_WRONLY | os .O_CREATE | os .O_TRUNC , os .FileMode (header .Mode ))
39+ file , err := os .OpenFile (
40+ abs ,
41+ os .O_WRONLY | os .O_CREATE | os .O_TRUNC ,
42+ os .FileMode (header .Mode ),
43+ )
3444 if err != nil {
3545 return fmt .Errorf ("unable to open file %s: %w" , header .Name , err )
3646 }
@@ -49,3 +59,13 @@ func Untar(in io.Reader, dir string) error {
4959 }
5060 }
5161}
62+
63+ // mitigate "G305: Zip Slip vulnerability".
64+ func sanitizeArchivePath (dir , path string ) (v string , err error ) {
65+ v = filepath .Join (dir , path )
66+ if ! strings .HasPrefix (v , filepath .Clean (dir )) {
67+ return "" , fmt .Errorf ("illegal filepath: %s" , path )
68+ }
69+
70+ return v , nil
71+ }
0 commit comments