GHSA-vfp3-v2gw-7wfq: Path Traversal
Summary
Echo'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.
Details
Root cause 1 — router.go lines 798-802: The 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.
go if !r.useEscapedPathForRouting && req.URL.RawPath != "" { path = req.URL.RawPath }
Root cause 2 — echo.go lines 559-568: StaticDirectoryHandler calls url.PathUnescape() on the path parameter before opening files. This converts %2F back to /, resolving admin/secret.txt on disk.
go if !disablePathUnescaping { tmpPath, err := url.PathUnescape(p) p = tmpPath } name := filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
PoC (Screenshot) Sample: <img width="1291" height="970" alt="image" src="https://github.com/user-attachments/assets/0bc58059-3e6d-4678-ab25-a5c79b006738" />
403: <img width="526" height="194" alt="image" src="https://github.com/user-attachments/assets/2f55ffdd-87b2-4a1b-8a13-130ebad0f257" />
Bypass with encoded slash: <img width="592" height="203" alt="image" src="https://github.com/user-attachments/assets/1191cd39-ae8f-4d7e-8fb1-cb9cf31f484f" />
Impact
Unauthorized 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.
Common affected pattern: go adminGroup := e.Group("/admin", authMiddleware) e.StaticFS("/", os.DirFS("public"))
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
go/github.com/labstack/echo/v4to a version that resolves this vulnerability.Fixed in 4.15.3 - Upgrade
Upgrade
go/github.com/labstack/echo/v5to a version that resolves this vulnerability.Fixed in 5.2.0
Event History
Frequently Asked Questions
Which deployments are exposed by this behavior?
Deployments using Echo's StaticDirectoryHandler are exposed when route-level access controls protect paths that can also be resolved by the static file handler. The default routing behavior uses the raw encoded path, creating the mismatch when an encoded slash is supplied.
What does an attacker need to exploit it?
An attacker can send a network request containing an encoded slash, such as %2F, in a path. The supplied vector has no authentication, user interaction, or special access prerequisites.
What can be done if an update cannot be applied immediately?
Avoid allowing the static handler to unescape request paths before filesystem resolution by disabling path unescaping where that handler configuration is available. Also avoid relying solely on route-level controls to protect files reachable through the static directory handler.
How can I check whether an application is affected?
Identify a static file path protected by a route-level rule, then test whether replacing a path separator with %2F causes the request to avoid the protected route while still returning the underlying file. A successful response to such a request indicates the router and static handler are handling the path differently.