no-exposed-private-fields
This rule detects sensitive fields (like passwords, tokens, secrets) in entity or DTO classes that are not excluded from serialization, which can lead to accide
Detect exposed sensitive fields in DTOs/entities
Rule Details
This rule detects sensitive fields (like passwords, tokens, secrets) in entity or DTO classes that are not excluded from serialization, which can lead to accidental exposure in API responses.
OWASP Mapping
- OWASP Top 10 2021: A01:2021 - Broken Access Control
- CWE: CWE-200 - Exposure of Sensitive Information to an Unauthorized Actor
- CVSS: 7.5 (High)
❌ Incorrect
@Entity()
class User {
id: string;
email: string;
password: string; // Exposed in API responses!
}✅ Correct
import { Exclude } from 'class-transformer';
@Entity()
class User {
id: string;
email: string;
@Exclude()
password: string; // Hidden from API responses
}
// Make sure to use ClassSerializerInterceptor
@UseInterceptors(ClassSerializerInterceptor)
@Controller('users')
class UsersController {
@Get(':id')
findOne(@Param('id') id: string) {
return this.usersService.findOne(id);
}
}Options
{
// Skip rule in test files (default: true)
allowInTests?: boolean;
}Detected Sensitive Field Names
password,passwordHash,hashedPasswordsecret,secretKey,apiSecrettoken,accessToken,refreshToken,authTokenprivateKey,encryptionKeyssn,socialSecurityNumbercreditCard,cardNumber
When Not To Use It
- For internal DTOs not used in API responses
- For DTOs that are explicitly mapped before sending to clients
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Dynamic Field Names
Why: Computed property names are not analyzed.
// ❌ NOT DETECTED - Dynamic field names
const sensitiveField = 'password';
class User {
[sensitiveField]: string; // Not recognized as password
}Mitigation: Use explicit field names. Avoid computed properties for sensitive data.
Custom Serializers
Why: Custom toJSON or serialize methods are not checked.
// ❌ NOT DETECTED - Password exposed in custom serializer
class User {
@Exclude()
password: string;
toJSON() {
return { ...this, password: this.password }; // Oops!
}
}Mitigation: Review custom serializers. Use class-transformer consistently.
Non-Standard Field Names
Why: Only predefined sensitive field names are detected.
// ❌ NOT DETECTED - Custom sensitive field name
class User {
mySecretCode: string; // Not in default list
}Mitigation: Configure custom sensitive field patterns in rule options.
Response Object Construction
Why: Manual response object building bypasses detection.
// ❌ NOT DETECTED - Manual response construction
@Get(':id')
async findOne(@Param('id') id: string) {
const user = await this.userService.findOne(id);
return { ...user, password: user.password }; // Exposed!
}Mitigation: Always use serialization interceptors. Use DTOs for responses.