mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-15 19:10:48 +02:00
* sftp: match permission paths on path-component boundaries Permission checks compared paths with raw string prefixes, so a permission entry for /tenants/alice also matched sibling paths such as /tenants/alice-archive, letting a scoped user read and overwrite another tenant's files. The home directory containment check had the same flaw. Route both through pathWithin, which cleans the paths and requires exact equality or a separator-delimited descendant. * sftp: clean permission path into a local when ranking matches
65 lines
2.1 KiB
Go
65 lines
2.1 KiB
Go
package sftpd
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/sftpd/user"
|
|
)
|
|
|
|
func TestPathWithin(t *testing.T) {
|
|
tests := []struct {
|
|
base string
|
|
candidate string
|
|
want bool
|
|
}{
|
|
{"/tenants/alice", "/tenants/alice", true},
|
|
{"/tenants/alice", "/tenants/alice/file.txt", true},
|
|
{"/tenants/alice", "/tenants/alice/sub/dir", true},
|
|
{"/tenants/alice", "/tenants/alice-archive", false},
|
|
{"/tenants/alice", "/tenants/alice-archive/secret.txt", false},
|
|
{"/tenants/alice", "/tenants/alice2", false},
|
|
{"/tenants/alice", "/tenants", false},
|
|
{"/tenants/alice/", "/tenants/alice/file.txt", true},
|
|
{"/tenants/alice", "/tenants/alice/../alice-archive", false},
|
|
{"/tenants/alice", "/tenants/alice/..", false},
|
|
{"/", "/", true},
|
|
{"/", "/anything", true},
|
|
}
|
|
for _, tt := range tests {
|
|
if got := pathWithin(tt.base, tt.candidate); got != tt.want {
|
|
t.Errorf("pathWithin(%q, %q) = %v, want %v", tt.base, tt.candidate, got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHasExplicitPermissionSiblingPrefix(t *testing.T) {
|
|
u := &user.User{
|
|
Username: "scoped",
|
|
HomeDir: "/",
|
|
Permissions: map[string][]string{
|
|
"/tenants/alice": {"read", "write", "list"},
|
|
},
|
|
}
|
|
|
|
if !HasExplicitPermission(u, "/tenants/alice/file.txt", PermRead, false) {
|
|
t.Error("expected read permission under /tenants/alice")
|
|
}
|
|
if HasExplicitPermission(u, "/tenants/alice-archive/secret.txt", PermRead, false) {
|
|
t.Error("ACL for /tenants/alice must not grant read on sibling /tenants/alice-archive")
|
|
}
|
|
if HasExplicitPermission(u, "/tenants/alice-archive/secret.txt", PermWrite, false) {
|
|
t.Error("ACL for /tenants/alice must not grant write on sibling /tenants/alice-archive")
|
|
}
|
|
}
|
|
|
|
func TestIsPathInHomeDirectorySiblingPrefix(t *testing.T) {
|
|
u := &user.User{Username: "alice", HomeDir: "/tenants/alice"}
|
|
|
|
if !isPathInHomeDirectory(u, "/tenants/alice/file.txt") {
|
|
t.Error("expected /tenants/alice/file.txt to be within home /tenants/alice")
|
|
}
|
|
if isPathInHomeDirectory(u, "/tenants/alice-archive/secret.txt") {
|
|
t.Error("home /tenants/alice must not match sibling /tenants/alice-archive")
|
|
}
|
|
}
|