Skip to content

Commit

Permalink
make tar file limit configurable in build time
Browse files Browse the repository at this point in the history
add unit tests

Signed-off-by: 2rigor <39034718+2rigor@users.noreply.github.com>
  • Loading branch information
2rigor authored and chkp-rigor committed Oct 27, 2024
1 parent 1cc8a41 commit 5f32a1c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
19 changes: 17 additions & 2 deletions pkg/file/tarutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import (
"io"
"os"
"path/filepath"
"strconv"
"strings"

"github.com/spf13/afero"

"github.com/anchore/stereoscope/internal/log"
)

const perFileReadLimit = 2 * GB
const perFileReadLimitDefault = 2 * GB
var perFileReadLimit int64 = perFileReadLimitDefault
var perFileReadLimitStr = "0" // allows configuring the above value during build time

var ErrTarStopIteration = fmt.Errorf("halt iterating tar")

Expand All @@ -39,6 +42,18 @@ type ErrFileNotFound struct {
Path string
}

func init() {
setPerFileReadLimit(perFileReadLimitStr)
}

func setPerFileReadLimit(val string) {
valInt64, err := strconv.ParseInt(val, 10, 64)
if err != nil || valInt64 <= 0 {
return
}
perFileReadLimit = valInt64
}

func (e *ErrFileNotFound) Error() string {
return fmt.Sprintf("file not found (path=%s)", e.Path)
}
Expand Down Expand Up @@ -178,7 +193,7 @@ func (v tarVisitor) visit(entry TarFileEntry) error {
// limit the reader on each file read to prevent decompression bomb attacks
numBytes, err := io.Copy(f, io.LimitReader(entry.Reader, perFileReadLimit))
if numBytes >= perFileReadLimit || errors.Is(err, io.EOF) {
return fmt.Errorf("zip read limit hit (potential decompression bomb attack)")
return fmt.Errorf("zip read limit hit (potential decompression bomb attack): copied %v, limit %v", numBytes, perFileReadLimit)
}
if err != nil {
return fmt.Errorf("unable to copy file: %w", err)
Expand Down
30 changes: 30 additions & 0 deletions pkg/file/tarutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,3 +430,33 @@ func Test_tarVisitor_visit(t *testing.T) {
})
}
}

func TestSetPerFileReadLimit_Valid(t *testing.T) {
// Test with a valid limit string
perFileReadLimit = perFileReadLimitDefault
setPerFileReadLimit("12345")

if perFileReadLimit != 12345 {
t.Errorf("Expected perFileReadLimit to be 12345, but got %d", perFileReadLimit)
}
}

func TestSetPerFileReadLimit_Invalid(t *testing.T) {
// Test with a invalid limit string
perFileReadLimit = perFileReadLimitDefault
setPerFileReadLimit("invalid")

if perFileReadLimit != perFileReadLimitDefault {
t.Errorf("Expected perFileReadLimit to be %d, but got %d", perFileReadLimitDefault, perFileReadLimit)
}
}

func TestSetPerFileReadLimit_Empty(t *testing.T) {
// Test with an empty limit string (default)
perFileReadLimit = perFileReadLimitDefault
setPerFileReadLimit("")

if perFileReadLimit != 2 * GB {
t.Errorf("Expected perFileReadLimit to be %d, but got %d", perFileReadLimitDefault, perFileReadLimit)
}
}

0 comments on commit 5f32a1c

Please sign in to comment.