Параметр whitelist

В экосистеме, где используется class-validator совместно с class-transformer (чаще всего в связке с NestJS), параметр whitelist относится к механизму автоматической фильтрации входных данных. Его основная задача — удаление всех свойств объекта, которые не описаны в DTO-классе через декораторы валидации.

Принцип работы механизма

При включённом whitelist входящий объект после преобразования в экземпляр класса проходит дополнительную стадию очистки. Поля, которые:

  • отсутствуют в классе DTO
  • не имеют декораторов валидации (@IsString, @IsInt, @IsOptional и т.д.)

удаляются из итогового объекта.

Фактически происходит приведение входного payload к строгой форме, описанной классом.

Базовая конфигурация в ValidationPipe

На практике параметр используется в конфигурации ValidationPipe:

import { ValidationPipe } from '@nestjs/common';

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
  }),
);

В этом режиме любые «лишние» свойства, пришедшие от клиента, автоматически исключаются.

Поведение при лишних полях

DTO:

import { IsString } from 'class-validator';

export class CreateUserDto {
  @IsString()
  name;
}

Входные данные:

{
  "name": "Alex",
  "role": "admin",
  "isAdmin": true
}

Результат при whitelist: true:

{
  "name": "Alex"
}

Свойства role и isAdmin удаляются, поскольку не описаны в DTO.

Влияние на безопасность данных

Основное назначение whitelist — защита от массового присваивания (mass assignment). Без фильтрации клиент может передать поля, которые:

  • не должны изменяться извне
  • относятся к внутренней логике системы
  • используются для повышения привилегий

Пример потенциальной уязвимости без whitelist:

{
  "name": "Alex",
  "isAdmin": true
}

Если DTO не ограничивает поля, подобные значения могут попасть в бизнес-логику без проверки.

Отличие от forbidNonWhitelisted

Параметр whitelist часто используется вместе с forbidNonWhitelisted, но их поведение принципиально различается.

new ValidationPipe({
  whitelist: true,
  forbidNonWhitelisted: true,
});
Параметр Поведение
whitelist удаляет лишние поля
forbidNonWhitelisted выбрасывает ошибку при наличии лишних полей

При включённом forbidNonWhitelisted вместо удаления данных происходит исключение:

{
  "statusCode": 400,
  "message": [
    "property role should not exist"
  ],
  "error": "Bad Request"
}

Таким образом:

  • whitelist: true — мягкая фильтрация
  • forbidNonWhitelisted: true — жёсткая валидация структуры

Взаимодействие с transform

Для корректной работы whitelist почти всегда используется вместе с transform: true:

new ValidationPipe({
  transform: true,
  whitelist: true,
});

transform: true обеспечивает преобразование plain object → class instance, после чего whitelist может корректно определить свойства, связанные с DTO.

Без transform фильтрация может работать непредсказуемо, поскольку объект остаётся обычным JSON-структурированным объектом.

Влияние на вложенные объекты

Whitelist не выполняет глубокую рекурсивную очистку сам по себе. Для вложенных структур требуется комбинация:

  • @ValidateNested()
  • @Type(() => Class)
  • включённый transform

Пример:

import { ValidateNested, IsString } from 'class-validator';
import { Type } from 'class-transformer';

class ProfileDto {
  @IsString()
  bio;
}

class CreateUserDto {
  @IsString()
  name;

  @ValidateNested()
  @Type(() => ProfileDto)
  profile;
}

При таком описании лишние поля внутри profile также могут быть удалены, но только при корректной трансформации вложенного объекта.

Работа с массивами объектов

При массивах объектов whitelist применяется к каждому элементу отдельно:

class CreateUsersDto {
  @ValidateNested({ each: true })
  @Type(() => CreateUserDto)
  users;
}

Каждый объект внутри массива проходит ту же процедуру фильтрации, что и одиночный DTO.

Особенности удаления полей

Whitelist удаляет только «неразрешённые» свойства. При этом:

  • null и undefined не считаются лишними полями
  • поля с декораторами, но без значений, остаются
  • приватные свойства JavaScript-объекта не учитываются

Ограничения механизма

Поведение whitelist имеет ряд особенностей:

  • не защищает от логических ошибок бизнес-уровня
  • не заменяет полноценную авторизацию и проверку прав
  • не фильтрует данные, поступающие не через DTO
  • не выполняет сложную нормализацию структуры

Его задача ограничена исключительно очисткой входного объекта от неизвестных полей на уровне DTO-схемы.

Практическое значение в архитектуре API

Whitelist формирует строгую контрактную модель API:

  • входные данные приводятся к фиксированной структуре
  • исключаются «лишние» параметры запроса
  • поведение API становится детерминированным
  • снижается риск непреднамеренного изменения модели данных

В системах с большим количеством внешних клиентов это становится базовым механизмом стабилизации интерфейса между клиентом и сервером