Skip to content

Commit

Permalink
cmd/rcd: Address ZipSlip vulnerability
Browse files Browse the repository at this point in the history
Don't create files outside of target
directory while unzipping.

Fixes #3529 reported by Nico Waisman at Semmle Security Team
  • Loading branch information
riptl authored and ncw committed Sep 29, 2019
1 parent b3cafe8 commit d9bdd05
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions cmd/rcd/rcd.go
Expand Up @@ -3,12 +3,14 @@ package rcd
import (
"archive/zip"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"

"github.com/rclone/rclone/cmd"
Expand Down Expand Up @@ -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
func unzip(src, dest string) (err error) {
dest = filepath.Clean(dest) + string(os.PathSeparator)

r, err := zip.OpenReader(src)
if err != nil {
return err
Expand All @@ -191,14 +195,18 @@ func unzip(src, dest string) (err error) {

// Closure to address file descriptors issue with all the deferred .Close() methods
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()
if err != nil {
return err
}
defer fs.CheckClose(rc, &err)

path := filepath.Join(dest, f.Name)

if f.FileInfo().IsDir() {
if err := os.MkdirAll(path, 0755); err != nil {
return err
Expand Down

0 comments on commit d9bdd05

Please sign in to comment.