Add comprehensive input validation to webhook and job DTOs #186

Closed
opened 2026-02-02 17:24:07 +00:00 by jason.woltje · 0 comments
Owner

Problem

Multiple DTOs lack proper input validation, allowing potential injection attacks, DoS, and data corruption.

Vulnerable DTOs

1. WebhookPayloadDto (apps/api/src/stitcher/dto/webhook.dto.ts)

  • issueNumber validated as string instead of number
  • repository has no pattern validation (path traversal risk)
  • comment has no length limit (DoS risk)
  • metadata has no depth/size limits (prototype pollution)

2. Coordinator Job DTOs (apps/api/src/coordinator-integration/dto/)

  • Missing max length constraints
  • No sanitization of user input
  • Unbounded object depths

Attack Vectors

  1. Integer overflow: issueNumber = "999999999999999999999"
  2. Path traversal: repository = "../../../malicious"
  3. XSS in Discord: comment = "<script>alert('XSS')</script>"
  4. DoS: comment field with 10MB string
  5. Prototype pollution: metadata.proto.isAdmin = true

Acceptance Criteria

  • Add @IsInt(), @Min(), @Max() to issueNumber
  • Add @Matches() pattern to repository field
  • Add @MaxLength() to all string fields
  • Add @Sanitize() decorator for HTML content
  • Create SafeMetadata type with nested validation
  • Add tests for malicious inputs
  • Document validation rules

Implementation

export class WebhookPayloadDto {
  @IsInt()
  @Min(1)
  @Max(999999)
  issueNumber!: number;
  
  @IsString()
  @Matches(/^[a-zA-Z0-9-_\/]+$/)
  @MaxLength(200)
  repository!: string;
  
  @IsOptional()
  @IsString()
  @MaxLength(10000)
  @Sanitize()
  comment?: string;
  
  @IsOptional()
  @IsObject()
  @ValidateNested()
  @Type(() => SafeMetadata)
  metadata?: SafeMetadata;
}

References

M4.2-Infrastructure verification report (2026-02-02)
Security review agent ID: a1b8b3f

## Problem Multiple DTOs lack proper input validation, allowing potential injection attacks, DoS, and data corruption. ## Vulnerable DTOs ### 1. WebhookPayloadDto (apps/api/src/stitcher/dto/webhook.dto.ts) - issueNumber validated as string instead of number - repository has no pattern validation (path traversal risk) - comment has no length limit (DoS risk) - metadata has no depth/size limits (prototype pollution) ### 2. Coordinator Job DTOs (apps/api/src/coordinator-integration/dto/) - Missing max length constraints - No sanitization of user input - Unbounded object depths ## Attack Vectors 1. Integer overflow: issueNumber = "999999999999999999999" 2. Path traversal: repository = "../../../malicious" 3. XSS in Discord: comment = "<script>alert('XSS')</script>" 4. DoS: comment field with 10MB string 5. Prototype pollution: metadata.__proto__.isAdmin = true ## Acceptance Criteria - [ ] Add @IsInt(), @Min(), @Max() to issueNumber - [ ] Add @Matches() pattern to repository field - [ ] Add @MaxLength() to all string fields - [ ] Add @Sanitize() decorator for HTML content - [ ] Create SafeMetadata type with nested validation - [ ] Add tests for malicious inputs - [ ] Document validation rules ## Implementation ```typescript export class WebhookPayloadDto { @IsInt() @Min(1) @Max(999999) issueNumber!: number; @IsString() @Matches(/^[a-zA-Z0-9-_\/]+$/) @MaxLength(200) repository!: string; @IsOptional() @IsString() @MaxLength(10000) @Sanitize() comment?: string; @IsOptional() @IsObject() @ValidateNested() @Type(() => SafeMetadata) metadata?: SafeMetadata; } ``` ## References M4.2-Infrastructure verification report (2026-02-02) Security review agent ID: a1b8b3f
jason.woltje added this to the M4.2-Infrastructure (0.0.4) milestone 2026-02-02 17:24:07 +00:00
jason.woltje added the securityapiapip1 labels 2026-02-02 17:24:07 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaic/stack#186