Vulnerability GHSA-4m76-xfj5-7975
Summary
Hono: `mount()` and `app.mount()` can forward a path that bypasses middleware scoped inside the mount prefix
Details
Summary
mount() and app.mount() remove the mount prefix from the request path and forward the rest to the mounted application. Two mistakes in that step let a crafted request reach a route of the mounted application that the outer application protects with path-scoped middleware, such as an authentication check on /app/admin/*. The outer application routes on the original path, so the middleware does not run.
Details
- Dynamic prefix (all affected versions): for a mount such as
/api/:tenant/*, the prefix was removed by the length of the route pattern, not of the matched prefix. A request with a longer or shorter first segment is cut in the middle, so/api/a/xxxxx/admin/secretreaches the mounted application as/admin/secret. - Re-normalization (since 4.12.21): the forwarded path was built from the decoded request path and assigned to
url.pathname, which turns a decoded backslash into/and collapses.../app/public%5C..%5Cadmin/secretreaches the mounted application as/admin/secret.
The fix removes the prefix segment by segment from the raw pathname, using the matched parameter values for its length. Route patterns that cannot be handled safely now throw: duplicate parameter names and a wildcard inside the last segment such as /assets*. A trailing slash in an app.mount() prefix no longer removes an extra segment.
Impact
An unauthenticated client can reach a route of a mounted application that the outer application protects with path-scoped middleware.
This affects applications that use mount() or app.mount() and rely on middleware registered on a sub-path inside the mount prefix for authentication or authorization.
Workarounds
Register the authentication middleware inside the mounted application.
Related Vulnerabilities
Other vulnerabilities affecting the same packages