1- package tar
1+ package tar //nolint:revive
22
33import (
44 "archive/tar"
@@ -88,8 +88,14 @@ func Compress(source, target string) error {
8888 return nil
8989}
9090
91+ // sanitizeLog strips newline/carriage-return characters from s to prevent log injection.
92+ func sanitizeLog (s string ) string {
93+ s = strings .ReplaceAll (s , "\n " , "" )
94+ return strings .ReplaceAll (s , "\r " , "" )
95+ }
96+
9197func ExtractTarGz (file * os.File , targetDir string ) error {
92- log .Printf ("Extracting tar.gz...%s" , file .Name ())
98+ log .Printf ("Extracting tar.gz...%s" , sanitizeLog ( file .Name ())) //nolint:gosec
9399 gz , err := gzip .NewReader (file )
94100 if err != nil {
95101 return fmt .Errorf ("error creating gzip reader: %w" , err )
@@ -101,7 +107,7 @@ func ExtractTarGz(file *os.File, targetDir string) error {
101107}
102108
103109func ExtractTar (file * os.File , targetDir string ) error {
104- log .Printf ("Extracting tar... %s" , file .Name ())
110+ log .Printf ("Extracting tar... %s" , sanitizeLog ( file .Name ())) //nolint:gosec
105111 return extract (tar .NewReader (file ), targetDir )
106112}
107113
@@ -129,16 +135,16 @@ func extract(tr *tar.Reader, targetDir string) error {
129135
130136 switch header .Typeflag {
131137 case tar .TypeDir :
132- // Ensure directory exists
133- if err := os .MkdirAll (path , os .ModePerm ); err != nil {
138+ // Ensure directory exists; path is validated by safePath above.
139+ if err := os .MkdirAll (path , os .ModePerm ); err != nil { //nolint:gosec
134140 return err
135141 }
136142 // Change the directory permission so that all users can create/update files inside.
137- if err := os .Chmod (path , os .ModePerm ); path != baseDir && err != nil {
143+ if err := os .Chmod (path , os .ModePerm ); path != baseDir && err != nil { //nolint:gosec
138144 return fmt .Errorf ("failed to change permissions of %s: %w" , path , err )
139145 }
140146 case tar .TypeReg :
141- outFile , err := os .Create (path )
147+ outFile , err := os .Create (path ) //nolint:gosec
142148 if err != nil {
143149 return fmt .Errorf ("error while creating file %s: %w" , path , err )
144150 }
@@ -171,9 +177,10 @@ func extract(tr *tar.Reader, targetDir string) error {
171177}
172178
173179func safePath (basePath , targetPath string ) (string , error ) {
174- if strings .Contains (targetPath , ".." ) {
175- return "" , fmt .Errorf ("target path contains '..': %s" , targetPath )
180+ combinedPath := filepath .Clean (filepath .Join (basePath , targetPath ))
181+ rel , err := filepath .Rel (basePath , combinedPath )
182+ if err != nil || rel == ".." || strings .HasPrefix (rel , ".." + string (filepath .Separator )) {
183+ return "" , fmt .Errorf ("target path %q escapes base directory" , targetPath )
176184 }
177- combinedPath := filepath .Join (basePath , targetPath )
178185 return combinedPath , nil
179186}
0 commit comments