How to Properly Sanitize NestJS Input?

Viewed 3355

I’m asking this as I can’t seem to get a straight answer.

So, NestJS has a very elegant way of handling validation by using decorators. That is, you define DTO classes with properties you expect, and annotate them with class-validator decorators. For example, assume we have a route that accepts input from a contact form.

class ContactInfoDTO {
     @IsString()
     @IsNotEmpty()
     name: string
     
     @IsEmail()
     email: string
     
     @IsString()
     @IsNotEmpty
     subject: string

     @IsString()
     @IsNotEmpty()
     body: string

}

This works great for validation. If I enter an invalid email, it will reject it as expected. But, here’s my question. What about input Sanitization? Say, for example, I enter a some JavaScript in the body parameter? Like, say, my body looks like this:

body: “Hello <script>//some malicious code here</script>”

Now, this is still accepted. Even though the script tags are not converted to HTML entities, which does pose a bit of a security risk.

So, my question is does NestJS have any kind of built-in Sanitization mechanisms? Is there proper documentation on this? Because I can’t really find any, despite this kind of thing being very important in the context of web development.

What’s the best practice for doing input Sanitization in NestJS?

2 Answers

Use sanitize-html with Transform like this:

import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import { IsString } from 'class-validator';
import * as sanitizeHtml from 'sanitize-html';

export class DocumentDto {
  @ApiProperty()
  @IsString()
  @Transform((value: string) => sanitizeHtml(value))
  public content: string;
}

You could use the class-sanitizer library and apply its decorators to your model's properties:

class ContactInfoDTO {
     @IsString()
     @IsNotEmpty()
     name: string
     
     @IsEmail()
     email: string
     
     @IsString()
     @IsNotEmpty
     subject: string

     @IsString()
     @IsNotEmpty()
     @Escape()
     body: string

}
Related