MCPcopy
hub / github.com/filebrowser/filebrowser / TestStatRejectsLinkedAncestorEscape

Function TestStatRejectsLinkedAncestorEscape

files/file_test.go:218–245  ·  view source on GitHub ↗

stat must reject a regular file reached through a symlinked ancestor that escapes the scope (GHSA-hf77-9m7w-fq8q), while still serving in-scope files.

(t *testing.T)

Source from the content-addressed store, hash-verified

216// stat must reject a regular file reached through a symlinked ancestor that
217// escapes the scope (GHSA-hf77-9m7w-fq8q), while still serving in-scope files.
218func TestStatRejectsLinkedAncestorEscape(t *testing.T) {
219 scope := t.TempDir()
220 if err := os.MkdirAll(filepath.Join(scope, "shared"), 0o755); err != nil {
221 t.Fatal(err)
222 }
223 if err := os.MkdirAll(filepath.Join(scope, "private"), 0o755); err != nil {
224 t.Fatal(err)
225 }
226 if err := os.WriteFile(filepath.Join(scope, "private", "secret.txt"), []byte("secret"), 0o600); err != nil {
227 t.Fatal(err)
228 }
229 if err := os.WriteFile(filepath.Join(scope, "shared", "ok.txt"), []byte("ok"), 0o600); err != nil {
230 t.Fatal(err)
231 }
232 if err := os.Symlink(filepath.Join(scope, "private"), filepath.Join(scope, "shared", "link")); err != nil {
233 t.Skipf("cannot create symlink: %v", err)
234 }
235
236 // Filesystem scoped to the shared directory, as a public share would be.
237 bfs := NewScopedFs(afero.NewOsFs(), filepath.Join(scope, "shared"))
238
239 if _, err := stat(&FileOptions{Fs: bfs, Path: "/link/secret.txt"}); !os.IsPermission(err) {
240 t.Fatalf("expected permission error for linked-ancestor escape, got %v", err)
241 }
242 if _, err := stat(&FileOptions{Fs: bfs, Path: "/ok.txt"}); err != nil {
243 t.Fatalf("expected in-scope file to be served, got %v", err)
244 }
245}
246
247type allowAllChecker struct{}
248

Callers

nothing calls this directly

Calls 3

NewScopedFsFunction · 0.85
statFunction · 0.85
MkdirAllMethod · 0.80

Tested by

no test coverage detected