HIGH nosql injectionadonisjs

Nosql Injection in Adonisjs

How Nosql Injection Manifests in Adonisjs

Nosql injection in Adonisjs applications typically occurs when user-supplied data is directly interpolated into MongoDB queries without proper sanitization. Unlike SQL injection, Nosql injection exploits the query language's ability to accept JavaScript objects and operators, allowing attackers to manipulate query logic.

Consider this common Adonisjs pattern:

const User = use('App/Models/User')
async show({ params }) {
  const user = await User.find(params.id)
  return user
}

This appears safe, but if params.id contains { $ne: null }, the query becomes:

{ _id: { $ne: null } }

This returns all users instead of one specific user—a classic BOLA (Broken Object Level Authorization) scenario enabled by Nosql injection.

More dangerous patterns include:

async search({ request }) {
  const query = request.input('query', {})
  return await User.where(query).fetch()
}

An attacker can send { "username": { "$ne": null }, "password": { "$ne": null } } to bypass authentication entirely. The where method accepts raw JavaScript objects, making it vulnerable when user input isn't validated.

Adonisjs's Lucid ORM (built on top of Mongoose-like query builders) provides several injection vectors:

  • where() with object parameters
  • orWhere() with dynamic conditions
  • orderBy() with unsanitized field names
  • limit() and skip() with numeric injection

The framework's flexibility becomes a liability when developers assume all input is safe. Nosql injection can also occur through:

async advancedSearch({ request }) {
  const filters = request.input('filters', {})
  const query = User.query()
  
  if (filters.age) query.where('age', filters.age)
  if (filters.name) query.where('name', filters.name)
  
  return await query.fetch()
}

Here, if filters.age contains { $gt: 0, $lt: 120, $ne: 25 }, the attacker can craft complex queries that return unintended data sets.

Adonisjs-Specific Detection

Detecting Nosql injection in Adonisjs requires examining both code patterns and runtime behavior. The most effective approach combines static analysis with dynamic scanning.

Code-level indicators include:

const User = use('App/Models/User')
async vulnerableMethod({ request }) {
  const unsafeInput = request.input('data')
  return await User
    .where('field', unsafeInput)  // Vulnerable
    .fetch()
}

Safe patterns use explicit validation:

async secureMethod({ request }) {
  const validated = request.only(['username', 'email'])
  return await User
    .where('username', validated.username)
    .where('email', validated.email)
    .fetch()
}

middleBrick's scanning specifically targets Adonisjs applications by:

  • Analyzing route handlers for direct query parameter usage
  • Checking for unsafe request.input() calls without validation
  • Examining model query construction patterns
  • Testing for BOLA vulnerabilities through IDOR-style attacks

The scanner sends crafted payloads like { $where: "this.password.length > 0" } and { $ne: null } to test query manipulation. For Adonisjs specifically, it checks:

GET /api/users?id[$ne]=null
GET /api/users?filter[username][$exists]=true
GET /api/users?sort[$meta]=textScore

middleBrick's LLM security module also detects if your Adonisjs API serves AI endpoints vulnerable to prompt injection, which often co-exists with Nosql injection vulnerabilities in modern applications.

Runtime detection involves monitoring for:

  • Unexpected query performance (indicating full collection scans)
  • Database logs showing unusual query patterns
  • Authentication bypass attempts

Adonisjs-Specific Remediation

Remediating Nosql injection in Adonisjs requires a defense-in-depth approach using the framework's built-in features.

First, always validate and sanitize input using Adonisjs's validation system:

const { validate } = use('Validator')

async secureShow({ params }) {
  const rules = { id: 'required|objectid' }
  const validation = await validate(params, rules)
  
  if (validation.fails()) {
    return response.status(400).send('Invalid ID format')
  }
  
  return await User.find(params.id)
}

The objectid rule ensures only valid MongoDB ObjectIDs pass through, blocking injection attempts.

For query building, use explicit whitelisting:

async search({ request }) {
  const allowedFields = ['username', 'email', 'age']
  const filters = request.only(allowedFields)
  
  const query = User.query()
  
  Object.keys(filters).forEach(field => {
    query.where(field, filters[field])
  })
  
  return await query.fetch()
}

This prevents attackers from injecting arbitrary operators by restricting fields to a known safe list.

For complex queries, use parameterized conditions:

async advancedSearch({ request }) {
  const { ageMin, ageMax } = request.only(['ageMin', 'ageMax'])
  
  const query = User.query()
  
  if (ageMin !== undefined) {
    query.where('age', '>=', parseInt(ageMin))
  }
  
  if (ageMax !== undefined) {
    query.where('age', '<=', parseInt(ageMax))
  }
  
  return await query.fetch()
}

Adonisjs's Lucid ORM provides additional safety through model scopes:

class User extends Model {
  static scopeAllowedSearch(query, filters) {
    const allowed = ['username', 'email']
    
    Object.keys(filters)
      .filter(field => allowed.includes(field))
      .forEach(field => {
        query.where(field, filters[field])
      })
    
    return query
  }
}

// Controller usage
async search({ request }) {
  const filters = request.only(['username', 'email'])
  return await User
    .allowedSearch(filters)
    .fetch()
}

For AI/ML endpoints in Adonisjs, implement output filtering:

async generateResponse({ request }) {
  const prompt = request.input('prompt', '')
  const response = await aiModel.generate(prompt)
  
  // Remove sensitive content
  const sanitized = response
    .replace(/API_KEY_[A-Z0-9]+/g, '[REDACTED]')
    .replace(/password|secret|token/gi, '[REDACTED]')
  
  return sanitized
}

Frequently Asked Questions

How does Nosql injection differ from SQL injection in Adonisjs applications?
Nosql injection exploits JavaScript object syntax and MongoDB operators like $where, $ne, $exists, while SQL injection targets SQL syntax. In Adonisjs, Nosql injection often bypasses authentication by manipulating query logic, whereas SQL injection typically extracts data through UNION queries or error-based techniques. The key difference is that Nosql queries are JSON-like objects that can contain executable JavaScript, making them more flexible but also more dangerous when user input isn't properly validated.
Can middleBrick detect Nosql injection in Adonisjs applications?
Yes, middleBrick specifically scans for Nosql injection patterns in Adonisjs applications. It tests endpoints with crafted payloads like { $ne: null }, { $where: "this.password.length > 0" }, and BOLA-style attacks. The scanner analyzes your API's unauthenticated attack surface, checking for vulnerable query construction patterns and authentication bypasses. middleBrick provides a security score (A-F) with specific findings about Nosql injection vulnerabilities, along with remediation guidance tailored to Adonisjs's Lucid ORM patterns.