Spot the vulnerability within this program
I wrote some code today to extract ZipFiles in Go. The code includes a security issue, can you spot it?
Not for use in a real environment!
package main
import (
"archive/zip"
"flag"
"fmt"
"io"
"log"
"os"
"path"
"path/filepath"
)
var file_name = flag.String("file_name",
"", "This is the zip file that you wish to extract")
func main() {
flag.Parse()
if *file_name == "" {
log.Fatal("Please enter a valid zipfile that you wish to extract")
}
r, err := zip.OpenReader(*file_name)
if err != nil {
log.Fatal(err)
}
defer r.Close()
current_dir, _ := os.Getwd()
done := make(chan bool, 1)
count := 0
for _, f := range r.File {
count++
go ExtractArchive(current_dir, f, done)
}
for count > 0 {
select {
case <-done:
count--
}
}
}
func ExtractArchive(current_directory string,
archive_file *zip.File, done chan bool) {
// Ensure that we can open the file
in, err := archive_file.Open()
if err != nil {
log.Fatal("Unable to open part of zip archive", err)
}
defer in.Close()
file_info := archive_file.FileInfo()
// Is it a directory? If so create the directory and return
if file_info.IsDir() {
os.MkdirAll(filepath.Join(current_directory,
path.Clean(archive_file.Name)), file_info.Mode())
done <- true
return
}
file_name := filepath.Join(current_directory, path.Clean(archive_file.Name))
out, err := os.Create(file_name)
fmt.Printf("\t Inflating contents of %s\n", archive_file.Name)
defer out.Close()
if err != nil {
log.Fatal(err)
}
if _, err = io.Copy(out, in); err != nil {
log.Println(err)
return
}
out.Sync()
done <- true
}