Phase3
This commit is contained in:
94
apps/node-agent/internal/files/safe_test.go
Normal file
94
apps/node-agent/internal/files/safe_test.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestResolvePath_BlocksTraversal(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
|
||||
tests := []string{
|
||||
"../outside",
|
||||
"../../etc/passwd",
|
||||
"foo/../../outside",
|
||||
}
|
||||
|
||||
for _, rel := range tests {
|
||||
t.Run(rel, func(t *testing.T) {
|
||||
_, err := ResolvePath(root, rel)
|
||||
if err == nil {
|
||||
t.Fatalf("expected path traversal error for %q", rel)
|
||||
}
|
||||
if err != ErrPathTraversal {
|
||||
t.Fatalf("expected ErrPathTraversal, got %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolvePath_AllowsNestedPaths(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
nested := filepath.Join(root, "world", "region")
|
||||
if err := os.MkdirAll(nested, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resolved, err := ResolvePath(root, "world/region")
|
||||
if err != nil {
|
||||
t.Fatalf("resolve nested path: %v", err)
|
||||
}
|
||||
if resolved != nested {
|
||||
t.Fatalf("resolved %q want %q", resolved, nested)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadFile_BlocksTraversal(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
secret := filepath.Join(filepath.Dir(root), "secret.txt")
|
||||
if err := os.WriteFile(secret, []byte("secret"), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = os.Remove(secret) })
|
||||
|
||||
_, _, err := ReadFile(root, "../"+filepath.Base(secret))
|
||||
if err == nil {
|
||||
t.Fatal("expected path traversal error")
|
||||
}
|
||||
if err != ErrPathTraversal {
|
||||
t.Fatalf("expected ErrPathTraversal, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteFile_AtomicWrite(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
rel := "server.properties"
|
||||
|
||||
if err := WriteFile(root, rel, "motd=Hello", true); err != nil {
|
||||
t.Fatalf("write file: %v", err)
|
||||
}
|
||||
|
||||
content, truncated, err := ReadFile(root, rel, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("read file: %v", err)
|
||||
}
|
||||
if truncated {
|
||||
t.Fatal("did not expect truncated read")
|
||||
}
|
||||
if content != "motd=Hello" {
|
||||
t.Fatalf("content %q want %q", content, "motd=Hello")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListDir_RejectsTraversal(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
|
||||
_, err := ListDir(root, "..")
|
||||
if err == nil {
|
||||
t.Fatal("expected path traversal error")
|
||||
}
|
||||
if err != ErrPathTraversal {
|
||||
t.Fatalf("expected ErrPathTraversal, got %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user