Files
stack/apps/api/src/federation/dto/connection.dto.ts
T
jason.woltjeandClaude Sonnet 4.5 01639fff95 feat(#285): Add input sanitization for XSS prevention
Security improvements:
- Create sanitization utility using sanitize-html library
- Add @Sanitize() and @SanitizeObject() decorators for DTOs
- Apply sanitization to vulnerable fields:
  - Connection rejection/disconnection reasons
  - Connection metadata
  - Identity linking metadata
  - Command payloads
- Remove script tags, event handlers, javascript: URLs
- Prevent data exfiltration, CSS-based XSS, SVG-based XSS

Changes:
- Add sanitize.util.ts with recursive sanitization functions
- Add sanitize.decorator.ts for class-transformer integration
- Update connection.dto.ts with sanitization decorators
- Update identity-linking.dto.ts with sanitization decorators
- Update command.dto.ts with sanitization decorators
- Add comprehensive test coverage including attack vectors

Part of M7.1 Remediation Sprint P1 security fixes.

Fixes #285

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-02-03 21:47:32 -06:00

69 lines
1.1 KiB
TypeScript

/**
* Connection DTOs
*
* Data Transfer Objects for federation connection API.
*/
import { IsString, IsUrl, IsOptional, IsObject, IsNumber } from "class-validator";
import { Sanitize, SanitizeObject } from "../../common/decorators/sanitize.decorator";
/**
* DTO for initiating a connection
*/
export class InitiateConnectionDto {
@IsUrl()
remoteUrl!: string;
}
/**
* DTO for accepting a connection
*/
export class AcceptConnectionDto {
@IsOptional()
@IsObject()
@SanitizeObject()
metadata?: Record<string, unknown>;
}
/**
* DTO for rejecting a connection
*/
export class RejectConnectionDto {
@IsString()
@Sanitize()
reason!: string;
}
/**
* DTO for disconnecting a connection
*/
export class DisconnectConnectionDto {
@IsOptional()
@IsString()
@Sanitize()
reason?: string;
}
/**
* DTO for incoming connection request (from remote instance)
*/
export class IncomingConnectionRequestDto {
@IsString()
instanceId!: string;
@IsUrl()
instanceUrl!: string;
@IsString()
publicKey!: string;
@IsObject()
capabilities!: Record<string, unknown>;
@IsNumber()
timestamp!: number;
@IsString()
signature!: string;
}