mirror of
https://github.com/rclone/rclone
synced 2025-01-17 22:27:30 +01:00
cmd/rcd: Address ZipSlip vulnerability
Don't create files outside of target directory while unzipping. Fixes #3529 reported by Nico Waisman at Semmle Security Team
This commit is contained in:
parent
44b603d2bd
commit
32d5af8fb6
@ -3,12 +3,14 @@ package rcd
|
|||||||
import (
|
import (
|
||||||
"archive/zip"
|
"archive/zip"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rclone/rclone/cmd"
|
"github.com/rclone/rclone/cmd"
|
||||||
@ -179,6 +181,8 @@ func downloadFile(filepath string, url string) error {
|
|||||||
|
|
||||||
// unzip is a helper function to unzip a file specified in src to path dest
|
// unzip is a helper function to unzip a file specified in src to path dest
|
||||||
func unzip(src, dest string) (err error) {
|
func unzip(src, dest string) (err error) {
|
||||||
|
dest = filepath.Clean(dest) + string(os.PathSeparator)
|
||||||
|
|
||||||
r, err := zip.OpenReader(src)
|
r, err := zip.OpenReader(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -191,14 +195,18 @@ func unzip(src, dest string) (err error) {
|
|||||||
|
|
||||||
// Closure to address file descriptors issue with all the deferred .Close() methods
|
// Closure to address file descriptors issue with all the deferred .Close() methods
|
||||||
extractAndWriteFile := func(f *zip.File) error {
|
extractAndWriteFile := func(f *zip.File) error {
|
||||||
|
path := filepath.Join(dest, f.Name)
|
||||||
|
// Check for Zip Slip: https://github.com/rclone/rclone/issues/3529
|
||||||
|
if !strings.HasPrefix(path, dest) {
|
||||||
|
return fmt.Errorf("%s: illegal file path", path)
|
||||||
|
}
|
||||||
|
|
||||||
rc, err := f.Open()
|
rc, err := f.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer fs.CheckClose(rc, &err)
|
defer fs.CheckClose(rc, &err)
|
||||||
|
|
||||||
path := filepath.Join(dest, f.Name)
|
|
||||||
|
|
||||||
if f.FileInfo().IsDir() {
|
if f.FileInfo().IsDir() {
|
||||||
if err := os.MkdirAll(path, 0755); err != nil {
|
if err := os.MkdirAll(path, 0755); err != nil {
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user