{"id":"GHSA-vfp3-v2gw-7wfq","summary":"Echo: Encoded slash (%2F) bypasses route-level protection and exposes static files","details":"### Summary\n\nEcho's router and static file handler disagree on URL path decoding. The router matches routes using the raw encoded path (preserving `%2F` as-is), while `StaticDirectoryHandler` unescapes `%2F` to `/` before resolving filesystem paths. This allows an attacker to bypass route-level access controls and read static files without authorization.\n\n### Details\n\n**Root cause 1 — `router.go` lines 798-802:**\nThe router uses `req.URL.RawPath` for route matching when `useEscapedPathForRouting` is false (the default). This means `/admin%2Fsecret.txt` is treated as a single path segment and does NOT match the `/admin/*` route pattern.\n\n```go\nif !r.useEscapedPathForRouting && req.URL.RawPath != \"\" {\n    path = req.URL.RawPath\n}\n```\n\n**Root cause 2 — `echo.go` lines 559-568:**\n`StaticDirectoryHandler` calls `url.PathUnescape()` on the path parameter before opening files. This converts `%2F` back to `/`, resolving `admin/secret.txt` on disk.\n\n```go\nif !disablePathUnescaping {\n    tmpPath, err := url.PathUnescape(p)\n    p = tmpPath\n}\nname := filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, \"/\")))\n```\n\n### PoC (Screenshot)\nSample:\n\u003cimg width=\"1291\" height=\"970\" alt=\"image\" src=\"https://github.com/user-attachments/assets/0bc58059-3e6d-4678-ab25-a5c79b006738\" /\u003e\n\n403:\n\u003cimg width=\"526\" height=\"194\" alt=\"image\" src=\"https://github.com/user-attachments/assets/2f55ffdd-87b2-4a1b-8a13-130ebad0f257\" /\u003e\n\nBypass with encoded slash:\n\u003cimg width=\"592\" height=\"203\" alt=\"image\" src=\"https://github.com/user-attachments/assets/1191cd39-ae8f-4d7e-8fb1-cb9cf31f484f\" /\u003e\n\n### Impact\n\nUnauthorized static file disclosure. Applications that protect route prefixes with authentication middleware while also serving static files from a broader root are vulnerable. An attacker only needs to encode the slash (`/` → `%2F`) in the URL to bypass all route-level protection.\n\nCommon affected pattern:\n```go\nadminGroup := e.Group(\"/admin\", authMiddleware)\ne.StaticFS(\"/\", os.DirFS(\"public\"))\n```","aliases":["CVE-2026-55677","GO-2026-6293"],"modified":"2026-08-26T15:25:53.302457857Z","published":"2026-08-25T16:13:29Z","database_specific":{"cwe_ids":["CWE-22"],"severity":"HIGH","github_reviewed":true,"github_reviewed_at":"2026-08-25T16:13:29Z","nvd_published_at":"2026-06-26T17:16:34Z"},"references":[{"type":"WEB","url":"https://github.com/labstack/echo/security/advisories/GHSA-vfp3-v2gw-7wfq"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-55677"},{"type":"WEB","url":"https://github.com/labstack/echo/pull/3009"},{"type":"WEB","url":"https://github.com/labstack/echo/pull/3011"},{"type":"WEB","url":"https://github.com/labstack/echo/commit/8d1ae9d3360a71672418856d58753af25f2c3986"},{"type":"WEB","url":"https://github.com/labstack/echo/commit/c3fa2a27ff92b2b8db360de614f999ef1da24725"},{"type":"PACKAGE","url":"https://github.com/labstack/echo"},{"type":"WEB","url":"https://github.com/labstack/echo/releases/tag/v4.15.3"},{"type":"WEB","url":"https://github.com/labstack/echo/releases/tag/v5.2.0"}],"affected":[{"package":{"name":"github.com/labstack/echo/v5","ecosystem":"Go","purl":"pkg:golang/github.com/labstack/echo/v5"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"5.2.0"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/08/GHSA-vfp3-v2gw-7wfq/GHSA-vfp3-v2gw-7wfq.json"}},{"package":{"name":"github.com/labstack/echo/v4","ecosystem":"Go","purl":"pkg:golang/github.com/labstack/echo/v4"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"4.15.3"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/08/GHSA-vfp3-v2gw-7wfq/GHSA-vfp3-v2gw-7wfq.json"}},{"package":{"name":"github.com/labstack/echo","ecosystem":"Go","purl":"pkg:golang/github.com/labstack/echo"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"last_affected":"3.3.10"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/08/GHSA-vfp3-v2gw-7wfq/GHSA-vfp3-v2gw-7wfq.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"}]}