Pii Leakage in Adonisjs with Mongodb
Pii Leakage in Adonisjs with Mongodb — how this specific combination creates or exposes the vulnerability
When building applications with AdonisJS and MongoDB, PII leakage commonly occurs because application code or query construction inadvertently returns sensitive fields such as email, phone, password_hash, or internal identifiers to the client. AdonisJS encourages explicit model fields via Lucid ORM, but developers sometimes bypass this by directly interacting with the MongoDB driver to gain performance or flexibility. This hybrid approach can expose raw MongoDB documents containing PII if field selection or projection is not strictly enforced.
At runtime, an endpoint that fetches a user document from MongoDB might return the full document, including fields like ssn, address, or password, especially when using methods like collection.find() without a projection that omits sensitive keys. Even if AdonisJS models define a serialize method to hide fields, a direct MongoDB call in a service or controller can bypass these protections. Additionally, aggregation pipelines or lookups that merge collections may unintentionally surface PII from related collections if stages do not explicitly exclude sensitive fields.
Another vector arises from dynamic query building where user-supplied filters or sort parameters are merged into MongoDB queries. If an API allows clients to specify which fields to return (e.g., via a fields query parameter) without strict denylisting, an attacker can request PII-bearing fields and receive them in the response. Unauthenticated or weakly authenticated endpoints that expose MongoDB-backed resources are especially risky, as attackers can probe for data exposure without needing credentials.
middleBrick detects these patterns through its LLM/AI Security and Data Exposure checks, which include system prompt leakage detection patterns and active prompt injection testing. For MongoDB-backed APIs, the scanner validates that responses exclude known PII categories and that no unauthenticated endpoints return sensitive documents. Findings include severity, context, and remediation guidance mapped to frameworks such as OWASP API Top 10 and compliance regimes like PCI-DSS and GDPR.
Mongodb-Specific Remediation in Adonisjs — concrete code fixes
To prevent PII leakage when using MongoDB with AdonisJS, enforce strict field selection and avoid returning sensitive data by default. Use projection to include only required fields, and ensure that helper methods or serializers are applied consistently across all data access paths.
Example 1: Safe find with projection in a controller
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import User from 'App/Models/User'
import { MongoClient } from 'mongodb'
export default class UsersController {
public async show({ params, response }: HttpContextContract) {
const client = new MongoClient('mongodb://127.0.0.1:27017')
await client.connect()
const db = client.db('appdb')
const users = db.collection('users')
// Explicitly include only safe fields; exclude PII
const projection = {
email: 0, // exclude email
password: 0, // exclude password hash
ssn: 0, // exclude sensitive personal data
address: 0, // exclude address
__v: 0,
}
const user = await users.findOne({ _id: params.id }, { projection })
await client.close()
if (!user) {
return response.notFound({ message: 'User not found' })
}
return response.ok(user)
}
}
Example 2: Using a model serializer to control output
import { DateTime } from 'luxon'
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'
export default class User extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public username: string
@column()
public email: string
@column()
public password: string
@column()
public ssn: string
public serialize() {
return {
id: this.id,
username: this.username,
// Do not include email, password, or ssn in serialized output
createdAt: this.createdAt.toFormat('yyyy-MM-dd'),
}
}
}
Example 3: Aggregation with explicit field exclusion
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { MongoClient } from 'mongodb'
export default class ReportsController {
public async index({ response }: HttpContextContract) {
const client = new MongoClient('mongodb://127.0.0.1:27017')
await client.connect()
const db = client.db('appdb')
const results = await db.collection('users').aggregate([
{
$project: {
username: 1,
role: 1,
// Explicitly exclude PII
email: 0,
password: 0,
ssn: 0,
address: 0,
phone: 0,
},
},
]).toArray()
await client.close()
return response.ok(results)
}
}
Additional recommendations
- Apply a global deny-list for known PII field names in query builders and service layers (e.g., email, phone, ssn, password).
- Validate and sanitize user-controlled field selectors; prefer an allow-list approach when exposing configurable fields.
- Ensure MongoDB users and roles follow the principle of least privilege so that even if PII is present in the database, unauthorized queries cannot access it.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |