agentsclimarketplace

Nestjs attack probe

Skill Dolphinllc/claude-security-skills/skills/offensive/web/nestjs-attack-probe

Defensive security skills for Claude Code and the Claude Agent SDK — web applications and generative AI systems.

Install
npx -y skills add Dolphinllc/claude-security-skills --skill nestjs-attack-probe

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Authorized self-pentest probe targeting NestJS-specific weaknesses. Tests global ValidationPipe gaps, missing @UseGuards on controller methods, default Swagger/OpenAPI exposure, WebSocket Gateway auth bypass, and TypeORM/Prisma raw query injection points discovered via OpenAPI. Use when the user asks to "pentest" their own NestJS app.

SKILL.md

4.5 KB, as published. Nobody here has run it

NestJS Attack Probe

Authorized probe of a NestJS 10.x/11.x app the user owns. Follow shared probing conventions — discover base URL from main.ts app.listen(...), process.env.PORT, Dockerfile EXPOSE, or nest-cli.json. Never hardcode.

NestJS-specific attack surface

  • Validation is opt-in: app.useGlobalPipes(new ValidationPipe()) without whitelist: true allows extra fields to flow through to handlers, defeating DTO-based validation.
  • Guards are opt-in: @UseGuards() on a controller class is per-class; per-method overrides + a missed method = anonymous endpoint.
  • @nestjs/swagger auto-mounts /api (or configured path) — by default unauthenticated.
  • WebSocket Gateways don't use the HTTP guard chain; they need their own auth in handleConnection.
  • @ApiBearerAuth() decorator is documentation only; it does not enforce the bearer token.

Procedure

  1. Authorization preflight + base URL discovery.
  2. Fetch Swagger if exposed: try /api, /api/docs, /swagger, /docs. The OpenAPI JSON is usually at <docs>/json or /api-json.
  3. Probe per rule table.

Rules

IDSeverityProbeConfirmed when
NEST-DOC-001mediumGET /api, /swagger, /docs200 Swagger UI = docs exposed (use as enumeration aid)
NEST-AUTH-001criticalFor each mutating route in OpenAPI without a security requirement, send unauthenticated request2xx = @UseGuards missing
NEST-AUTH-002highFor routes with security: bearerAuth, send obviously-malformed token2xx = guard returns true instead of throwing
NEST-PIPE-001highSubmit a body with extra fields not in DTO ({"role": "admin", ...valid...})Response shows extra field accepted = whitelist: true not set; combined with mass-assignment lookup → high
NEST-PIPE-002mediumSubmit body with type-confusion (string where number expected)500 instead of 422 = transformation/validation pipe partially configured
NEST-DTO-001mediumFind a DTO without class-validator decorators (parse OpenAPI: properties with no constraints); send semantically invalid data (e.g., email: "not-email")2xx = no @IsEmail() enforcement
NEST-WS-001highIf /socket.io or custom gateway endpoint advertised, connect without auth headerConnection upgraded + message received = no canActivate in handleConnection
NEST-CORS-001highOPTIONS /api/* with Origin: https://evil.test and credentialsACAO + ACAC: true = enableCors({ origin: '*' or true, credentials: true })
NEST-EXC-001mediumForce an error via malformed JSON / DB constraint violation500 with full stack / class names = exception filter leaking
NEST-COOKIE-001highLogin, capture cookie. Test httpOnly, secure, sameSite flags via Set-Cookie headerMissing flags = misconfigured cookie-parser/session
NEST-RATE-001medium10 rapid POST /auth/loginNo 429 = @nestjs/throttler not registered

Wrong vs. right

NEST-PIPE-001 (extra-field bypass)

// ❌ main.ts — pipe registered without whitelist
app.useGlobalPipes(new ValidationPipe());
// ✅
app.useGlobalPipes(new ValidationPipe({
  whitelist: true,
  forbidNonWhitelisted: true,
  transform: true,
}));

NEST-AUTH-001 (per-method guard miss)

// ❌ Class guard, but one method missing decoration override + decorator removed
@Controller("orders")
@UseGuards(JwtAuthGuard)
export class OrdersController {
  @Get() list() { /* guarded */ }
  @Public()                        // someone added this for tests, forgot to remove
  @Delete(":id") remove() { /* now anonymous */ }
}
// ✅
@Controller("orders")
@UseGuards(JwtAuthGuard, RolesGuard)
export class OrdersController {
  @Get() list() { /* ... */ }
  @Roles("admin")
  @Delete(":id") remove() { /* ... */ }
}

References

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.