When middleware.StaticWithConfig is used with Browse: true and a requested directory has no index file
(default index.html), the generated directory listing is not scoped to StaticConfig.Root. Instead, it
enumerates the filesystem root of StaticConfig.Filesystem, which can leak directory/file names (and sizes)
outside the intended Root subtree.
Expected
If Root: "public", listing should only include entries under public/.
Actual
Listing includes entries outside Root.
Repro
base := filepath.Join("poc", "static_data")
e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
Root: "public",
Browse: true,
Filesystem: os.DirFS(base),
}))
Steps:
- Create base/public/ (no base/public/index.html)
- Create base/secret.txt (outside public)
- GET / -> listing shows secret.txt
Code pointer
middleware/static.go: listDir() uses fs.WalkDir(filesystem, ".", ...) so it walks FS root, not name/Root/
requested dir.
Suggested fix
Scope directory listing to the requested directory (derived from Root + request path).
Prefer fs.ReadDir for a non-recursive listing:
entries, err := fs.ReadDir(filesystem, name) (and use entry.Info() for size)
Alternative:
sub, err := fs.Sub(filesystem, name) and list . within that sub-FS (non-recursive), handling err.
When
middleware.StaticWithConfigis used withBrowse: trueand a requested directory has no index file(default
index.html), the generated directory listing is not scoped toStaticConfig.Root. Instead, itenumerates the filesystem root of
StaticConfig.Filesystem, which can leak directory/file names (and sizes)outside the intended
Rootsubtree.Expected
If
Root: "public", listing should only include entries underpublic/.Actual
Listing includes entries outside
Root.Repro
Steps:
Code pointer
middleware/static.go:
listDir()usesfs.WalkDir(filesystem, ".", ...)so it walks FS root, notname/Root/requested dir.
Suggested fix
Scope directory listing to the requested directory (derived from
Root+ request path).Prefer
fs.ReadDirfor a non-recursive listing:entries, err := fs.ReadDir(filesystem, name)(and useentry.Info()for size)Alternative:
sub, err := fs.Sub(filesystem, name)and list.within that sub-FS (non-recursive), handlingerr.