safely join paths derived from archive headers

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman
2021-04-15 08:55:29 -04:00
parent d5dfaaba53
commit 484730435b
2 changed files with 106 additions and 9 deletions
+79
View File
@@ -3,6 +3,8 @@ package file
import (
"crypto/sha256"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
@@ -12,6 +14,7 @@ import (
"testing"
"github.com/go-test/deep"
"github.com/stretchr/testify/assert"
)
func equal(r1, r2 io.Reader) (bool, error) {
@@ -173,3 +176,79 @@ func TestContentsFromZip(t *testing.T) {
t.Errorf("full result: %s", string(b))
}
}
// looks like there isn't a helper for this yet? https://github.com/stretchr/testify/issues/497
func assertErrorAs(expectedErr interface{}) assert.ErrorAssertionFunc {
return func(t assert.TestingT, actualErr error, i ...interface{}) bool {
return errors.As(actualErr, &expectedErr)
}
}
func TestSafeJoin(t *testing.T) {
tests := []struct {
prefix string
args []string
expected string
errAssertion assert.ErrorAssertionFunc
}{
// go cases...
{
prefix: "/a/place",
args: []string{
"somewhere/else",
},
expected: "/a/place/somewhere/else",
errAssertion: assert.NoError,
},
{
prefix: "/a/place",
args: []string{
"somewhere/../else",
},
expected: "/a/place/else",
errAssertion: assert.NoError,
},
{
prefix: "/a/../place",
args: []string{
"somewhere/else",
},
expected: "/place/somewhere/else",
errAssertion: assert.NoError,
},
// zip slip examples....
{
prefix: "/a/place",
args: []string{
"../../../etc/passwd",
},
expected: "",
errAssertion: assertErrorAs(&errZipSlipDetected{}),
},
{
prefix: "/a/place",
args: []string{
"../",
"../",
},
expected: "",
errAssertion: assertErrorAs(&errZipSlipDetected{}),
},
{
prefix: "/a/place",
args: []string{
"../",
},
expected: "",
errAssertion: assertErrorAs(&errZipSlipDetected{}),
},
}
for _, test := range tests {
t.Run(fmt.Sprintf("%+v:%+v", test.prefix, test.args), func(t *testing.T) {
actual, err := safeJoin(test.prefix, test.args...)
test.errAssertion(t, err)
assert.Equal(t, test.expected, actual)
})
}
}