The vulnerability is an access control bypass in @koa/router where middleware is skipped if a router's prefix contains path parameters (e.g., new Router({ prefix: '/:tenant' })).
The root cause lies in how these parameterized prefixes were applied to middleware and routes. The Layer.setPrefix function would naively concatenate the prefix with the layer's path. When a middleware was added to a router with a parameterized prefix, its path would become something like /:tenant(.*). The path-to-regexp library would then generate a regular expression that the router's matching logic could not correctly use to match incoming requests, causing the middleware to be "silently dropped".
The vulnerable functions are:
Layer.setPrefix in lib/layer.js: It incorrectly concatenated prefixes with parameters.
Router.use in lib/router.js: It used Layer.setPrefix to apply the flawed prefix logic to middleware layers.
Router.routes in lib/router.js: It returned the middleware that relied on the flawed matching logic, ultimately failing to execute the necessary middleware.
The fix, part of a complete rewrite from JavaScript to TypeScript in commit d53e17f284557b1f417946f9807ee52290c3c759, addresses this by fundamentally changing how prefixes with parameters are handled. The new implementation detects if a prefix has parameters. If so, it avoids prepending the prefix to individual layers. Instead, the routes() method generates a special wrapper middleware. This wrapper's sole responsibility is to match the parameterized prefix, extract the prefix parameters, and then call the main router dispatch function. This separation of concerns ensures that both the prefix parameters are correctly parsed and the subsequent middleware and route handlers are executed as expected.