agentsclimarketplace

Nestjs security scan

Skill Dolphinllc/claude-security-skills/skills/defensive/web/nestjs-security-scan

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-security-scan

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

Defensive security scan for NestJS applications. Detects missing global ValidationPipe with whitelist, controllers without @UseGuards, DTOs without class-validator decorators, permissive CORS, missing helmet, exception filters leaking stack traces, TypeORM raw queries with template literals, and WebSocket gateways without auth. Invoke when the user asks to "review", "audit", or "scan" a NestJS project.

SKILL.md

4.4 KB, as published. Nobody here has run it

NestJS Security Scan

Defensive scan for NestJS 10.x / 11.x. Reports findings using the shared scoring schema.

Scope

  • main.ts / bootstrap()
  • *.controller.ts, *.gateway.ts, *.resolver.ts
  • DTO files (*.dto.ts)
  • Modules registering APP_GUARD, APP_PIPE, APP_FILTER, APP_INTERCEPTOR

Procedure

  1. Read main.ts to confirm global pipes/guards/filters/helmet/CORS.
  2. Walk every controller method for guards and DTOs.
  3. Inspect DTO classes for class-validator decorators.

Rules

IDSeverityDetectionFix
NEST-PIPE-001highNo global ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true }) in main.tsRegister globally; this is the single biggest input-validation lever in Nest
NEST-DTO-001highDTO class without any class-validator decorators (@IsString, @IsEmail, etc.) used as @Body() typeDecorate every field; @ValidateNested for nested objects
NEST-DTO-002mediumDTO uses any / Record<string, unknown> for bodyDefine a typed DTO
NEST-GUARD-001criticalMutating controller method (@Post/@Put/@Patch/@Delete) without @UseGuards(...) and no global APP_GUARD providing authApply @UseGuards(JwtAuthGuard) (or global guard)
NEST-GUARD-002high@Public() decorator (or @SkipAuth()) used on admin / write endpointsRemove; restrict to login/health
NEST-CORS-001highapp.enableCors({ origin: '*', credentials: true }) or origin: true with credentialsProvide origin allowlist function
NEST-HDR-001mediumhelmet() not applied (app.use(helmet()))Apply in main.ts before listen
NEST-EXC-001mediumCustom ExceptionFilter returning exception.stack / full message to clientReturn generic message; log details server-side
NEST-TYPEORM-001criticalrepository.query(\SELECT … ${var}`)/manager.query` with template literalUse query("SELECT … WHERE id = $1", [var])
NEST-TYPEORM-002highcreateQueryBuilder().where(\col = '${var}'`)`Use .where("col = :v", { v: var })
NEST-WS-001high@WebSocketGateway() with no canActivate guard on handleConnection and emits user-tied dataImplement auth in gateway lifecycle
NEST-COOKIE-001highCookieParser/session secret literal in codeRead from ConfigService; require non-empty at boot
NEST-SWAGGER-001mediumSwaggerModule.setup mounted in production without auth on the docs pathGate docs path behind auth or env flag
NEST-RATE-001medium@nestjs/throttler not registered, or no throttle on /auth/loginRegister ThrottlerModule and apply guard

Wrong vs. right

NEST-PIPE-001 + NEST-DTO-001 (validation gap)

// ❌ Body is whatever the client sends
@Post()
create(@Body() body: any) { return this.svc.create(body); }
// ✅ main.ts
app.useGlobalPipes(new ValidationPipe({
  whitelist: true,
  forbidNonWhitelisted: true,
  transform: true,
}));

// ✅ DTO
export class CreateUserDto {
  @IsEmail() email!: string;
  @IsString() @Length(8, 128) password!: string;
  @IsOptional() @IsEnum(Role) role?: Role;
}

@Post()
create(@Body() dto: CreateUserDto) { return this.svc.create(dto); }

NEST-GUARD-001 (no guard on mutation)

// ❌
@Delete(':id')
remove(@Param('id') id: string) { return this.svc.remove(id); }
// ✅
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@Delete(':id')
remove(@Param('id') id: string) { return this.svc.remove(id); }

NEST-TYPEORM-001 (raw query injection)

// ❌
const rows = await repo.query(`SELECT * FROM users WHERE email = '${email}'`);
// ✅
const rows = await repo.query('SELECT * FROM users WHERE email = $1', [email]);

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.