Skip to main content
interlace
Plugin: nestjs-securityRules

no-missing-validation-pipe

Requires ValidationPipe for DTO input parameters

Require ValidationPipe for DTO input parameters

The rule provides LLM-optimized error messages (Compact 2-line format) with actionable security guidance:

Error Message Format

The rule provides LLM-optimized error messages (Compact 2-line format) with actionable security guidance:

🔒 CWE-20 OWASP:A06 CVSS:7.5 | Improper Input Validation detected | HIGH [SOC2,PCI-DSS,HIPAA,GDPR,ISO27001]
   Fix: Review and apply the recommended fix | https://owasp.org/Top10/A06_2021/

Message Components

ComponentPurposeExample
Risk StandardsSecurity benchmarksCWE-20 OWASP:A06 CVSS:7.5
Issue DescriptionSpecific vulnerabilityImproper Input Validation detected
Severity & ComplianceImpact assessmentHIGH [SOC2,PCI-DSS,HIPAA,GDPR,ISO27001]
Fix InstructionActionable remediationFollow the remediation steps below
Technical TruthOfficial referenceOWASP Top 10

Rule Details

This rule detects NestJS route handlers that accept DTO parameters without ValidationPipe, which can lead to injection attacks through unvalidated input.

OWASP Mapping

  • OWASP Top 10 2021: A03:2021 - Injection
  • CWE: CWE-20 - Improper Input Validation
  • CVSS: 8.6 (High)

❌ Incorrect

@Controller('users')
class UsersController {
  @Post()
  create(@Body() dto: CreateUserDto) {
    // No validation - malicious input can pass through!
  }
}

✅ Correct

import { UsePipes, ValidationPipe } from '@nestjs/common';

// Class-level validation
@Controller('users')
@UsePipes(new ValidationPipe())
class UsersController {
  @Post()
  create(@Body() dto: CreateUserDto) {}
}

// Or in main.ts (global)
app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
    forbidNonWhitelisted: true,
    transform: true,
  }),
);

Options

{
  // Skip rule in test files (default: true)
  allowInTests?: boolean;

  // Scan the project's module and bootstrap files for an app-wide pipe
  // (APP_PIPE / app.useGlobalPipes) and stay silent when one exists
  // (default: true)
  detectGlobalPipes?: boolean;

  // Assume a global pipe without scanning (default: false)
  assumeGlobalPipes?: boolean;

  // Require an explicit per-route pipe even where a global one would validate
  // the input. Off by default: the rule reports only shapes no ValidationPipe
  // can validate — missing annotation, any, unknown, object, inline type
  // literals (default: false)
  requireExplicitPipe?: boolean;
}
new ValidationPipe({
  whitelist: true, // Strip non-decorated properties
  forbidNonWhitelisted: true, // Throw on extra properties
  transform: true, // Auto-transform to DTO types
});

When Not To Use It

  • If you have app.useGlobalPipes(new ValidationPipe()) in main.ts, set assumeGlobalPipes: true

Cross-File Detection

Registered app-wide

The rule scans the project's module and bootstrap files and stays silent when it finds an app-wide registration, so this is not a false positive:

// main.ts
app.useGlobalPipes(new ValidationPipe({ whitelist: true }));

Turn the scan off with detectGlobalPipes: false if you want the routes reported anyway. What the scan still cannot resolve is a registration built at runtime or supplied by a library — assumeGlobalPipes: true covers those.

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Conditional Pipe Application

Why: Pipes applied conditionally are not tracked.

// ❌ NOT DETECTED - Conditional validation
if (process.env.NODE_ENV === 'production') {
  app.useGlobalPipes(new ValidationPipe());
}

Mitigation: Always apply validation unconditionally.

Custom Validation Decorators

Why: Custom decorators wrapping validation are not recognized.

// ❌ NOT DETECTED - Custom decorator includes validation
@CustomValidated() // Internally uses ValidationPipe
class MyController {}

Mitigation: Document custom decorators. Use standard @UsePipes.

Module-Level Providers

Why: Validation pipes as providers are not detected.

// ❌ NOT DETECTED - Pipe as module provider
@Module({
  providers: [{ provide: APP_PIPE, useClass: ValidationPipe }]
})

Mitigation: Configure assumeGlobalPipes for modules with APP_PIPE provider.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.