# @nestjs/platform-fastify: Path-scoped middleware bypass via absolute-form request targets

Absolute-form request targets bypass path-scoped Nest middleware on the Fastify adapter, letting unauthenticated requests reach protected route handlers.

- Payout: Research
- Severity: high
- Program: NestJS
- Found by: zerovulnlabs
- Disclosed: 2026-09-30
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-9c5c-9qcx-q35q
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-9c5c-9qcx-q35q
- Tags: area:web domain:web impact:internal-access kind:research platform:ghsa sev:high tech:nodejs technique:incomplete-fix technique:parser-differential vuln:access-control vuln:auth-bypass

**Target:** Fastify HTTP adapter middleware engine (middie) and route matching
**Root cause:** The bundled @fastify/middie fork and FastifyAdapter's createMiddlewareFactory() matched middleware path regexps against the raw request target (req.originalUrl) without resolving absolute-form targets to a path, while find-my-way does resolve them, so router and middleware disagreed on the path.
**Steps:**
1. Set up a Nest app on @nestjs/platform-fastify with middleware bound via forRoutes({ path: 'users', method: RequestMethod.GET }) that blocks requests.
2. Note supertest/light-my-request emit origin-form only, so open a raw TCP socket to the server.
3. Write `GET http://127.0.0.1:3000/users HTTP/1.1` with `Host: 127.0.0.1:3000` and `Connection: close`.
4. Observe the handler returns `protected data` instead of `blocked by auth middleware`.
**How found:** Noticed the router (find-my-way) resolves absolute-form targets before matching while the middleware engine and adapter re-check matched against the raw target; also that passing routerOptions suppressed reflection of deprecated top-level router options into initialConfig.routerOptions, widening normalization mismatch.
**Exploitation:** Any client controlling the raw request line sends an absolute-form target; Node's HTTP server accepts it and no special config is needed. The router dispatches to the protected handler while path-scoped auth middleware is skipped, yielding auth/authz bypass. A reverse proxy rewriting to origin-form mitigates.
**Insight:** When a framework forks a dependency to carry a local fix, check whether it missed later upstream security fixes; and test middleware path matching with non-origin-form request targets (absolute-form, `OPTIONS *`) since test clients like supertest never emit them.

## Proof of concept (copied exactly from the original report)

**Raw socket request with absolute-form target bypassing middleware**

```
const { connect } = require('node:net');

const socket = connect(3000, '127.0.0.1', () => {
  socket.write(
    'GET http://127.0.0.1:3000/users HTTP/1.1\r\n' +
      'Host: 127.0.0.1:3000\r\n' +
      'Connection: close\r\n\r\n',
  );
});
socket.pipe(process.stdout);
```

