Fix XSS in API Responses in NestJS
XSS in APIs occurs when untrusted input is reflected in the response body without proper encoding or sanitization, often exacerbated by incorrect 'Content-Type' headers. In NestJS, this typically happens when developers return raw strings or unvalidated DTO properties that a browser might interpret as executable HTML/JavaScript.
The Vulnerable Pattern
@Get('profile')
@Header('Content-Type', 'text/html')
getProfile(@Query('username') username: string) {
// CRITICAL: Directly reflecting query param into an HTML response
return `Welcome back, ${username}`;
}
The Secure Implementation
To kill XSS in NestJS: 1. Stop returning 'text/html' from controllers; stick to 'application/json'. 2. Use 'class-validator' and 'class-transformer' to enforce strict input schemas, stripping unexpected tags. 3. Use 'helmet' middleware to enforce 'nosniff' headers, preventing browsers from MIME-sniffing JSON as HTML. 4. If you must return HTML, use a library like 'dompurify' to sanitize inputs against a strict whitelist before interpolation.
// 1. Define a strict DTO export class ProfileDto { @IsString() @MaxLength(20) username: string; }// 2. Controller implementation @Get(‘profile’) @UsePipes(new ValidationPipe()) getProfile(@Query() query: ProfileDto) { // SECURE: Return JSON, let the frontend handle safe rendering return { message: ‘Welcome back’, user: query.username }; }
// 3. Global Security (main.ts) import helmet from ‘helmet’; app.use(helmet()); // Sets X-Content-Type-Options: nosniff and CSP
Your API Responses API
might be exposed to XSS
74% of API Responses apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.