Interlace ESLint
ESLint Interlace
NestJSRules

require-class-validator

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

Require class-validator decorators on DTO properties

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 DTO classes with properties that lack class-validator decorators, which can lead to invalid or malicious data being accepted.

OWASP Mapping

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

❌ Incorrect

class CreateUserDto {
  name: string; // No validation
  email: string; // No validation
}

✅ Correct

import { IsString, IsEmail, IsNotEmpty, MinLength } from 'class-validator';

class CreateUserDto {
  @IsString()
  @IsNotEmpty()
  @MinLength(2)
  name: string;

  @IsEmail()
  @IsNotEmpty()
  email: string;
}

Options

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

Common Validators

DecoratorPurpose
@IsString()Must be a string
@IsNumber()Must be a number
@IsEmail()Must be valid email
@IsNotEmpty()Cannot be empty
@MinLength(n)Minimum string length
@MaxLength(n)Maximum string length
@IsOptional()Field is optional
@IsUUID()Must be valid UUID
@IsEnum(enum)Must be enum value

When Not To Use It

  • For internal DTOs that don't accept external input
  • For DTOs used only in tests

Known False Negatives

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

Inherited Properties

Why: Validators on parent class properties are not visible.

// ❌ NOT DETECTED - Validation on parent
class BaseDto {
  @IsString()
  name: string;
}
class CreateUserDto extends BaseDto {
  email: string; // Only this is checked
}

Mitigation: Add validators on subclass or use composition.

Index Signatures

Why: Dynamic properties are not validated.

// ❌ NOT DETECTED - Index signature
class ConfigDto {
  @IsString()
  name: string;

  [key: string]: any; // Arbitrary properties accepted!
}

Mitigation: Avoid index signatures in DTOs. Use strict typing.

Nested Objects Without @ValidateNested

Why: Nested validation requires explicit decorator.

// ❌ NOT DETECTED - Nested object not validated
class OrderDto {
  @IsString()
  orderId: string;

  items: OrderItemDto[]; // Items not validated!
}

Mitigation: Use @ValidateNested() and @Type() for nested objects.

Optional Fields Without @IsOptional

Why: Optional TypeScript properties may still require validation.

// ❌ NOT DETECTED - Optional but no IsOptional
class UpdateUserDto {
  name?: string; // TypeScript optional, but validation unclear
}

Mitigation: Explicitly add @IsOptional() on optional fields.

On this page