Skip to content

fix(static): reject encoded path separators that bypass route-level middleware (v4 backport)#3011

Merged
vishr merged 1 commit into
v4from
fix/static-encoded-slash-v4
Jun 14, 2026
Merged

fix(static): reject encoded path separators that bypass route-level middleware (v4 backport)#3011
vishr merged 1 commit into
v4from
fix/static-encoded-slash-v4

Conversation

@vishr

@vishr vishr commented Jun 14, 2026

Copy link
Copy Markdown
Member

v4 backport of #3009 (released in v5.2.0) for GHSA-vfp3-v2gw-7wfq.

Summary

An encoded path separator (%2F or %5C) in a static file URL could bypass route-level access control and disclose files. The router matches against the raw, still-encoded path, so %2F is not a separator — /admin%2Fsecret.txt skips a protected /admin/* group, falls through to static serving, which then unescaped %2F/ and served admin/secret.txt.

v4 is affected on both static surfaces:

  • echo_fs.go StaticDirectoryHandler (used by Static/StaticFS) — vulnerable to %2F and %5C (it used OS-specific filepath.Clean).
  • middleware/static.go — vulnerable to %2F (it already used path.Clean, so not %5C).

Fix

  • Both surfaces reject a wildcard containing an encoded separator (%2F/%2f or %5C/%5c) with 404 before unescaping, via a shared internal/pathutil helper.
  • StaticDirectoryHandler switched from filepath.Clean+ToSlash to path.Clean (OS-independent; keeps backslash literal on Windows).

Tests

  • New regression tests for %2F, %5C, double-encoded %252F, group StaticFS, and the static middleware on a group; unit test for the detector.
  • Updated two existing cases (open redirect vulnerability, Directory redirect#01) that asserted the old %2f-unescaped redirect — they now correctly assert 404 + no Location.
  • go test -race ./... and go vet ./... pass.

Targets the v4 branch for a v4.15.3 release; the advisory will be amended to add the github.com/labstack/echo (v4) affected product once tagged.

🤖 Generated with Claude Code

…iddleware

Backport of the v5 fix (GHSA-vfp3-v2gw-7wfq) to the v4 line.

An encoded path separator (%2F or %5C) in a static file URL could bypass route-level
access control and disclose files. The router matches routes against the raw,
still-encoded request path, so %2F is not a segment separator -- /admin%2Fsecret.txt
never matches a protected /admin/* group and falls through to the static handler,
which then unescaped %2F back to "/" and served admin/secret.txt from disk.

Both static serving paths are affected and fixed:

- StaticDirectoryHandler (echo_fs.go), used by Static/StaticFS, and the static
  middleware (middleware/static.go) now reject a wildcard containing an encoded
  separator (%2F/%2f or %5C/%5c) with 404 before unescaping, via a shared internal
  helper (internal/pathutil).
- StaticDirectoryHandler resolves the file name with path.Clean instead of the
  OS-specific filepath.Clean, so a decoded backslash stays a literal character
  rather than being treated as a separator on Windows. (The middleware already used
  path.Clean.)

Tests cover %2F, %5C, double-encoded %252F, group StaticFS, and the static
middleware on a group, plus a unit test for the separator detector.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vishr vishr force-pushed the fix/static-encoded-slash-v4 branch 2 times, most recently from e48da56 to 1ceeeb5 Compare June 14, 2026 16:10
@vishr vishr merged commit c3fa2a2 into v4 Jun 14, 2026
7 of 8 checks passed
@vishr vishr deleted the fix/static-encoded-slash-v4 branch June 14, 2026 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant