Skip to content

Commit b58df7c

Browse files
committed
add testcase and document StaticDirectoryHandler disablePathUnescaping param
1 parent 99fcc1f commit b58df7c

3 files changed

Lines changed: 17 additions & 4 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
hello world file

echo.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -616,10 +616,13 @@ func (e *Echo) StaticFS(pathPrefix string, filesystem fs.FS, middleware ...Middl
616616
// StaticDirectoryHandler creates handler function to serve files from provided file system
617617
// When disablePathUnescaping is set then file name from path is not unescaped and is served as is.
618618
//
619-
// Note: Router is matching against unescaped path and using disablePathUnescaping=false here can lead to serving files
620-
// outside of the intended directory - if there are Routes that are meant to forbit some subset of the served filesystem
621-
// to be accessed, but inconsistency between how Router sees an unescaped path and this function will use an escaped path.
622-
// Enabling RouterConfig.UseEscapedPathForMatching makes path escaping in static files and router consistent.
619+
// Note: when disablePathUnescaping=false, the handler decodes the wildcard param before serving.
620+
// If route guards (e.g. e.GET("/admin/*", forbidden)) are used to restrict parts of the
621+
// filesystem, an encoded separator (%2F) or encoded dot-dot (%2E%2E) in the URL can resolve to
622+
// a path that the router never matched against the guard route. Enabling
623+
// RouterConfig.UseEscapedPathForMatching does NOT fix this — it changes which path the router
624+
// uses for matching but still lets path.Clean resolve ".." segments into a guarded directory.
625+
// Do not rely on route guards alone to restrict a filesystem served by this handler.
623626
// See https://github.com/labstack/echo/security/advisories/GHSA-vfp3-v2gw-7wfq
624627
func StaticDirectoryHandler(fileSystem fs.FS, disablePathUnescaping bool) HandlerFunc {
625628
return func(c *Context) error {

echo_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,15 @@ func TestEcho_StaticFS(t *testing.T) {
275275
expectStatus: http.StatusOK,
276276
expectBodyStartsWith: "private file",
277277
},
278+
{
279+
name: "ok, file with space in name is served when path unescaping is enabled",
280+
givenPrefix: "/",
281+
givenFs: os.DirFS("_fixture/dist/public"),
282+
givenEnablePathUnescapingStaticFiles: true,
283+
whenURL: "/hello%20world.txt",
284+
expectStatus: http.StatusOK,
285+
expectBodyStartsWith: "hello world file",
286+
},
278287
{
279288
name: "do not allow directory traversal (slash - unix separator)",
280289
givenPrefix: "/",

0 commit comments

Comments
 (0)