mirror of
https://github.com/henrygd/beszel.git
synced 2026-08-19 08:47:46 +02:00
ghupdate: add checksum verification and extraction path containment guard
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package ghupdate
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
@@ -43,3 +46,59 @@ func TestExtractFailure(t *testing.T) {
|
||||
t.Fatal("Expected Extract to fail due to missing tar.gz file")
|
||||
}
|
||||
}
|
||||
|
||||
func TestArchivePath(t *testing.T) {
|
||||
destDir := t.TempDir()
|
||||
for _, name := range []string{
|
||||
"",
|
||||
"..",
|
||||
filepath.Join("..", "file"),
|
||||
filepath.Join("dir", "..", "..", "file"),
|
||||
string(os.PathSeparator) + filepath.Join("tmp", "file"),
|
||||
} {
|
||||
if _, err := archivePath(destDir, name); err == nil {
|
||||
t.Errorf("expected %q to be rejected", name)
|
||||
}
|
||||
}
|
||||
|
||||
name := filepath.Join("dir", "file")
|
||||
if path, err := archivePath(destDir, name); err != nil || path != filepath.Join(destDir, name) {
|
||||
t.Errorf("archivePath(%q) = %q, %v", name, path, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractTarGzRejectsPathTraversal(t *testing.T) {
|
||||
testDir := t.TempDir()
|
||||
archivePath := filepath.Join(testDir, "malicious.tar.gz")
|
||||
destDir := filepath.Join(testDir, "extract")
|
||||
escapedPath := filepath.Join(testDir, "escaped")
|
||||
|
||||
archive, err := os.Create(archivePath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gz := gzip.NewWriter(archive)
|
||||
tw := tar.NewWriter(gz)
|
||||
if err := tw.WriteHeader(&tar.Header{Name: "../escaped", Mode: 0600, Size: 1}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := tw.Write([]byte("x")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := tw.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := gz.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := archive.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := extract(archivePath, destDir); err == nil {
|
||||
t.Fatal("expected path traversal archive to be rejected")
|
||||
}
|
||||
if _, err := os.Stat(escapedPath); !os.IsNotExist(err) {
|
||||
t.Fatalf("path traversal wrote %s", escapedPath)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user