From f152df95b4842c94ce95b9a9b634738009964c0b Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Tue, 24 Sep 2024 13:33:33 +0300 Subject: [PATCH] Add protection against decompression bomb for bz2, gz, zip, and tar --- bz2/bz2.go | 8 +++++++- gz/gz.go | 8 +++++++- tar/tar.go | 6 +++++- zip/zip.go | 8 +++++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/bz2/bz2.go b/bz2/bz2.go index 254dd19..930be46 100644 --- a/bz2/bz2.go +++ b/bz2/bz2.go @@ -22,6 +22,12 @@ import ( // ////////////////////////////////////////////////////////////////////////////////// // +// MaxReadLimit is the maximum read limit for decompression bomb +// protection (default: 1GB) +var MaxReadLimit int64 = 1024 * 1024 * 1024 + +// ////////////////////////////////////////////////////////////////////////////////// // + var ( ErrNilReader = fmt.Errorf("Reader can not be nil") ErrEmptyInput = fmt.Errorf("Path to input file can not be empty") @@ -76,7 +82,7 @@ func Read(r io.Reader, output string) error { } bw := bufio.NewWriter(fd) - _, err = io.Copy(bw, bzip2.NewReader(r)) + _, err = io.Copy(bw, io.LimitReader(bzip2.NewReader(r), MaxReadLimit)) bw.Flush() fd.Close() diff --git a/gz/gz.go b/gz/gz.go index 179f91e..4965e25 100644 --- a/gz/gz.go +++ b/gz/gz.go @@ -23,6 +23,12 @@ import ( // ////////////////////////////////////////////////////////////////////////////////// // +// MaxReadLimit is the maximum read limit for decompression bomb +// protection (default: 1GB) +var MaxReadLimit int64 = 1024 * 1024 * 1024 + +// ////////////////////////////////////////////////////////////////////////////////// // + var ( ErrNilReader = fmt.Errorf("Reader can not be nil") ErrEmptyInput = fmt.Errorf("Path to input file can not be empty") @@ -83,7 +89,7 @@ func Read(r io.Reader, output string) error { } bw := bufio.NewWriter(fd) - _, err = io.Copy(bw, cr) + _, err = io.Copy(bw, io.LimitReader(cr, MaxReadLimit)) bw.Flush() fd.Close() diff --git a/tar/tar.go b/tar/tar.go index 924dae4..f392a9c 100644 --- a/tar/tar.go +++ b/tar/tar.go @@ -32,6 +32,10 @@ var UpdateTimes = true // outside target directory var AllowExternalLinks = false +// MaxReadLimit is the maximum read limit for decompression bomb +// protection (default: 1GB) +var MaxReadLimit int64 = 1024 * 1024 * 1024 + // ////////////////////////////////////////////////////////////////////////////////// // var ( @@ -148,7 +152,7 @@ func createFile(h *tar.Header, r io.Reader, path string) error { } bw := bufio.NewWriter(fd) - _, err = io.Copy(bw, r) + _, err = io.Copy(bw, io.LimitReader(r, MaxReadLimit)) if err != nil { return err diff --git a/zip/zip.go b/zip/zip.go index ce6e69e..cedff9f 100644 --- a/zip/zip.go +++ b/zip/zip.go @@ -22,6 +22,12 @@ import ( // ////////////////////////////////////////////////////////////////////////////////// // +// MaxReadLimit is the maximum read limit for decompression bomb +// protection (default: 1GB) +var MaxReadLimit int64 = 1024 * 1024 * 1024 + +// ////////////////////////////////////////////////////////////////////////////////// // + var ( ErrNilReader = fmt.Errorf("Reader can not be nil") ErrEmptyOutput = fmt.Errorf("Path to output directory can not be empty") @@ -95,7 +101,7 @@ func Read(r io.ReaderAt, dir string) error { } bw := bufio.NewWriter(fd) - _, err = io.Copy(bw, zfd) + _, err = io.Copy(bw, io.LimitReader(zfd, MaxReadLimit)) bw.Flush() fd.Close()