prevent security warning about "Zip Slip" in RPI camera downloader (#6096)
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -20,12 +21,36 @@ const (
|
||||
maxInboundRPICameraSize = 10 * 1024 * 1024
|
||||
)
|
||||
|
||||
func absolutePathInside(base string, candidate string) (string, error) {
|
||||
baseAbs, err := filepath.Abs(filepath.Clean(base))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
candidateAbs, err := filepath.Abs(filepath.Clean(candidate))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
rel, err := filepath.Rel(baseAbs, candidateAbs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
|
||||
return "", fmt.Errorf("path escapes base directory")
|
||||
}
|
||||
|
||||
return candidateAbs, nil
|
||||
}
|
||||
|
||||
func dumpTar(src io.Reader) error {
|
||||
uncompressed, err := gzip.NewReader(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
baseDir := "."
|
||||
tr := tar.NewReader(uncompressed)
|
||||
|
||||
for {
|
||||
@@ -38,16 +63,22 @@ func dumpTar(src io.Reader) error {
|
||||
return err
|
||||
}
|
||||
|
||||
var targetPath string
|
||||
targetPath, err = absolutePathInside(baseDir, filepath.Join(baseDir, header.Name))
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid archive entry: %s", header.Name)
|
||||
}
|
||||
|
||||
switch header.Typeflag {
|
||||
case tar.TypeDir:
|
||||
err = os.Mkdir(header.Name, header.FileInfo().Mode())
|
||||
err = os.Mkdir(targetPath, header.FileInfo().Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
case tar.TypeReg:
|
||||
var f *os.File
|
||||
f, err = os.OpenFile(header.Name, os.O_WRONLY|os.O_CREATE, header.FileInfo().Mode())
|
||||
f, err = os.OpenFile(targetPath, os.O_WRONLY|os.O_CREATE, header.FileInfo().Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user