В экосистеме, где используется class-validator совместно
с class-transformer (чаще всего в связке с NestJS),
параметр whitelist относится к механизму автоматической
фильтрации входных данных. Его основная задача — удаление всех свойств
объекта, которые не описаны в DTO-классе через декораторы валидации.
При включённом whitelist входящий объект после
преобразования в экземпляр класса проходит дополнительную стадию
очистки. Поля, которые:
@IsString,
@IsInt, @IsOptional и т.д.)удаляются из итогового объекта.
Фактически происходит приведение входного payload к строгой форме, описанной классом.
На практике параметр используется в конфигурации
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 не ограничивает поля, подобные значения могут попасть в бизнес-логику без проверки.
Параметр 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 — жёсткая валидация
структурыДля корректной работы 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 не считаются лишними
полямиПоведение whitelist имеет ряд особенностей:
Его задача ограничена исключительно очисткой входного объекта от неизвестных полей на уровне DTO-схемы.
Whitelist формирует строгую контрактную модель API:
В системах с большим количеством внешних клиентов это становится базовым механизмом стабилизации интерфейса между клиентом и сервером