Files
codeql/go/ql/test/query-tests/Security/CWE-022/tarslip.go
2022-05-20 10:07:19 -07:00

91 lines
2.5 KiB
Go

package main
import (
"archive/tar"
"errors"
"io"
"os"
"path"
"path/filepath"
"strings"
)
func untarBad(reader io.Reader, prefix string) {
tarReader := tar.NewReader(reader)
header, _ := tarReader.Next()
os.MkdirAll(path.Dir(header.Name), 0755) // NOT OK
}
func untarGood(reader io.Reader, prefix string) {
tarReader := tar.NewReader(reader)
header, _ := tarReader.Next()
if !strings.HasPrefix(header.Name, prefix) {
panic("tar contents corrupted")
}
os.MkdirAll(path.Dir(header.Name), 0755) // OK
}
// GOOD: checks `header.Name` indirectly.
func untarGoodIndirect(reader io.Reader, prefix string) {
tarReader := tar.NewReader(reader)
header, _ := tarReader.Next()
if !strings.HasPrefix(filepath.Join(prefix, header.Name), prefix) {
panic("tar contents corrupted")
}
os.MkdirAll(path.Dir(header.Name), 0755) // OK
}
func checkPathTar(s, prefix string) error {
if !strings.HasPrefix(filepath.Join(prefix, s), prefix) {
return errors.New("tar contents corrupted")
}
return nil
}
// GOOD: uses a function that returns an error
// when the header is not safe to use. Flagged because we can't currently
// recognise that `errors.New` always returns non-nil.
func untarGoodIndirectUsingFunction(reader io.Reader, prefix string) {
tarReader := tar.NewReader(reader)
header, _ := tarReader.Next()
if checkPathTar(header.Name, prefix) != nil {
panic("tar contents corrupted")
}
os.MkdirAll(path.Dir(header.Name), 0755) // OK
}
func checkPathBoolTar(s, prefix string) bool {
return strings.HasPrefix(filepath.Join(prefix, s), prefix)
}
// GOOD: uses a checker function returning a boolean
// to ensure `header` is safe to unpack. Currently flagged because the callee
// has no 'return true' or 'return false' statements, but rather directly
// returns a sanitizer guard function.
func untarGoodIndirectUsingBoolFunction(reader io.Reader, prefix string) {
tarReader := tar.NewReader(reader)
header, _ := tarReader.Next()
if !checkPathBoolTar(header.Name, prefix) {
panic("tar contents corrupted")
}
os.MkdirAll(path.Dir(header.Name), 0755) // OK
}
func checkPathBoolStmtTar(s, prefix string) bool {
if strings.HasPrefix(filepath.Join(prefix, s), prefix) {
return true
}
return false
}
// GOOD: uses a checker function returning a boolean to ensure `header`
// is safe to unpack.
func untarGoodIndirectUsingBoolStmtFunction(reader io.Reader, prefix string) {
tarReader := tar.NewReader(reader)
header, _ := tarReader.Next()
if !checkPathBoolStmtTar(header.Name, prefix) {
panic("tar contents corrupted")
}
os.MkdirAll(path.Dir(header.Name), 0755) // OK
}