no-select-sensitive-fields
ESLint rule documentation for no-select-sensitive-fields
📡 Live from GitHub — This documentation is fetched directly from no-select-sensitive-fields.md and cached for 6 hours.
Keywords: CWE-200, information exposure, password, Mongoose, security
Detects queries that may return sensitive fields like passwords, tokens, or API keys.
Detects queries that may return sensitive fields like passwords, tokens, or API keys.
⚠️ This rule warns by default in the recommended config.
Quick Summary
| Aspect | Details |
|---|---|
| CWE Reference | CWE-200 (Information Exposure) |
| OWASP | A01:2021 - Broken Access Control |
| Severity | Medium (CVSS: 5.3) |
| Category | Security |
Rule Details
Queries without field selection may inadvertently return sensitive data.
❌ Incorrect
// Returns all fields including password
const user = await User.findById(id);
res.json(user); // Password hash exposed!
// Explicit select of sensitive fields
const user = await User.findById(id).select('+password');✅ Correct
// Exclude sensitive fields
const user = await User.findById(id).select('-password -refreshToken');
// Select only needed fields
const user = await User.findById(id).select('name email avatar');
// Use schema select: false for sensitive fields
const userSchema = new Schema({
password: { type: String, select: false },
refreshToken: { type: String, select: false },
});Options
{
"rules": {
"mongodb-security/no-select-sensitive-fields": [
"warn",
{
"sensitiveFields": [
"password",
"refreshToken",
"apiKey",
"secret",
"ssn"
]
}
]
}
}When Not To Use It
- In authentication flows where password comparison is needed
- When schema already has
select: falseon all sensitive fields
Known False Negatives
The following patterns are not detected due to static analysis limitations:
Schema-Level select: false
Why: Schema definitions in other files are not visible.
// ❌ NOT DETECTED - Schema has select: false (safe but not known)
// userSchema.ts: password: { type: String, select: false }
const user = await User.findById(id); // Password already excludedMitigation: This is a false positive risk. Use schema-level exclusion as primary defense.
Variable Field Selection
Why: Select arguments from variables are not analyzed.
// ❌ NOT DETECTED - Fields from variable
const fields = '+password';
const user = await User.findById(id).select(fields);Mitigation: Use inline select strings. Define field lists as constants.
Aggregation Pipeline
Why: Aggregation $project stages are not checked.
// ❌ NOT DETECTED - Sensitive field in aggregation
const users = await User.aggregate([
{ $match: { active: true } },
{ $project: { password: 1 } }, // Includes password!
]);Mitigation: Review aggregation pipelines. Use $unset for sensitive fields.
Lean Queries
Why: Lean queries bypass middleware that might filter fields.
// ❌ NOT DETECTED - Lean returns raw document
const user = await User.findById(id).lean(); // Includes all fieldsMitigation: Always use .select() with .lean(). Define projection inline.