Skip to content

Static middleware Browse directory listing is not scoped to Root (WalkDir uses filesystem root) #2886

@shblue21

Description

@shblue21

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:

  1. Create base/public/ (no base/public/index.html)
  2. Create base/secret.txt (outside public)
  3. GET / -> listing shows secret.txt
Image Image

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions