MEDIUM out of bounds readadonisjs

Out Of Bounds Read in Adonisjs

How Out Of Bounds Read Manifests in Adonisjs

Out Of Bounds Read (OOB Read) vulnerabilities in Adonisjs applications typically occur when code attempts to access array or string indices beyond their actual length. In Adonisjs, this often manifests through improper handling of request parameters, database query results, or user-provided data.

A common pattern in Adonisjs controllers involves accessing array elements without validating their existence. For example:

class UserController {
  async show({ params }) {
    const user = await User.find(params.id)
    // OOB Read risk: accessing properties without checking if user exists
    return {
      name: user.name,
      email: user.email,
      role: user.role // If user is null, this throws TypeError
    }
  }
}

Another frequent scenario involves parsing request bodies where Adonisjs's automatic JSON parsing can lead to OOB Read if the input structure is unexpected:

class ProductController {
  async create({ request }) {
    const data = request.post()
    // OOB Read risk: assuming specific array structure
    const tags = data.tags || []
    return {
      name: data.name,
      tag1: tags[0], // If tags is undefined or empty, this is undefined
      tag2: tags[1], // Same issue
      tag3: tags[2]  // Same issue
    }
  }
}

Database query results can also trigger OOB Read vulnerabilities when Adonisjs's Lucid ORM returns unexpected results:

class ReportController {
  async generate({ params }) {
    const sales = await Sale.query()
      .where('product_id', params.productId)
      .orderBy('created_at', 'desc')
      .limit(10)
      
    // OOB Read risk: assuming at least one result exists
    const latestSale = sales[0] // If sales is empty, this is undefined
    return {
      latestPrice: latestSale.price, // TypeError if latestSale is undefined
      totalSales: sales.length
    }
  }
}

Adonisjs's middleware system can propagate OOB Read issues when data flows through multiple layers without proper validation:

class AuthMiddleware {
  async handle({ request, auth }, next) {
    const token = request.header('authorization')?.replace('Bearer ', '')
    const payload = jwt.verify(token, process.env.JWT_SECRET)
    
    // OOB Read risk: assuming payload has specific structure
    request.user = {
      id: payload.sub,
      email: payload.email, // If payload doesn't have email, this is undefined
      permissions: payload.permissions || []
    }
    
    await next()
  }
}

Adonisjs-Specific Detection

Detecting Out Of Bounds Read vulnerabilities in Adonisjs requires both static analysis and runtime scanning. The framework's structure creates specific patterns that make detection more straightforward than in other Node.js frameworks.

Static analysis should focus on controller methods and middleware that access array indices or object properties without null checks. Look for patterns like:

const result = await Model.find(id)
return result.property // Missing null check

middleBrick's API security scanner includes specific checks for Adonisjs applications. When scanning an Adonisjs endpoint, middleBrick tests for OOB Read vulnerabilities by:

  • Sending malformed request bodies with unexpected array structures
  • Testing database query responses with empty result sets
  • Verifying authentication middleware handles missing claims properly
  • Checking for proper error handling when accessing undefined properties

The scanner's black-box approach is particularly effective for Adonisjs because it tests the actual runtime behavior without needing access to source code. For example, when scanning a user profile endpoint, middleBrick will:

POST /api/users/profile
Content-Type: application/json

{
  "userIds": []
}

// Tests if the endpoint handles empty arrays properly
// Checks if it crashes when accessing [0] on empty arrays

middleBrick's OpenAPI analysis also helps detect OOB Read vulnerabilities by cross-referencing your API specification with actual runtime behavior. If your spec defines a response object with required fields, but the implementation doesn't validate their presence, middleBrick will flag this discrepancy.

Integration with Adonisjs's validation system is another detection vector. The framework's validate method can prevent many OOB Read issues, but only if properly configured:

const { validate } = use('Validator')

async show({ request }) {
  const data = await validate(request.post(), {
    tags: 'array|min:1', // Ensures tags exists and has at least one element
    name: 'required|string'
  })
  
  if (data.fails()) {
    return response.badRequest(data.messages())
  }
  
  // Now it's safe to access tags[0]
  return {
    name: data.name,
    firstTag: data.tags[0]
  }
}

Adonisjs-Specific Remediation

Remediating Out Of Bounds Read vulnerabilities in Adonisjs requires a combination of defensive programming practices and leveraging the framework's built-in features. The key is to always validate data before accessing it.

The most effective approach is using Adonisjs's schema-based validation system:

const { schema } = use('Validator')

async create({ request }) {
  const newUserSchema = schema.create({
    name: schema.string({}, [rules.required()]),
    email: schema.string({}, [
      rules.required(),
      rules.email()
    ]),
    tags: schema.array.optional([
      rules.minLength(1)
    ])
  })
  
  const payload = await request.validate({
    schema: newUserSchema,
    messages: {
      'tags.minLength': 'At least one tag is required'
    }
  })
  
  // Safe to access payload.tags[0] because validation passed
  return {
    success: true,
    firstTag: payload.tags ? payload.tags[0] : null
  }
}

For database operations, Adonisjs's Lucid ORM provides safe access patterns. Instead of directly accessing array indices, use optional chaining and nullish coalescing:

async show({ params }) {
  const user = await User.find(params.id)
  
  // Safe access pattern
  return {
    name: user?.name ?? 'Unknown',
    email: user?.email ?? 'unknown@example.com',
    role: user?.role ?? 'guest'
  }
}

Middleware is an excellent place to centralize OOB Read protection in Adonisjs applications. Create a validation middleware that ensures required data exists:

class DataValidationMiddleware {
  async handle({ request }, next) {
    const body = request.post()
    
    // Ensure required fields exist
    if (!body?.userIds || !Array.isArray(body.userIds)) {
      return response.badRequest({
        error: 'userIds must be an array'
      })
    }
    
    // Ensure array has elements before accessing
    if (body.userIds.length === 0) {
      return response.badRequest({
        error: 'userIds array cannot be empty'
      })
    }
    
    await next()
  }
}

// Register in start/kernel.js
const globalMiddleware = [
  'App/Middleware/DataValidationMiddleware'
]

Adonisjs's error handling system can also help prevent OOB Read vulnerabilities from causing application crashes. Configure a global error handler:

// app/Exceptions/Handler.js
class ExceptionHandler {
  async handle(error, { response }) {
    if (error instanceof TypeError && error.message.includes('Cannot read property')) {
      // Log the incident and return safe response
      console.warn('OOB Read attempt:', error.message)
      return response.status(500).json({
        error: 'Internal server error'
      })
    }
    
    return response.status(500).json({
      error: 'Internal server error'
    })
  }
}

For API endpoints that return data, always provide default values or proper error responses:

async fetchProducts({ request }) {
  const category = request.input('category', 'all')
  const products = await Product.query()
    .where('category', category)
    .limit(10)
  
  // Safe access with default values
  return products.map(product => ({
    id: product.id,
    name: product.name || 'Unnamed Product',
    price: product.price ?? 0,
    description: product.description || ''
  }))
}

Frequently Asked Questions

How does middleBrick detect Out Of Bounds Read vulnerabilities in Adonisjs applications?
middleBrick performs black-box scanning of Adonisjs endpoints, testing for OOB Read by sending malformed requests with unexpected array structures, empty result sets, and missing properties. It verifies that your application handles these edge cases without crashing and provides a security score based on how well it manages boundary conditions.
Can Adonisjs's built-in validation prevent all Out Of Bounds Read vulnerabilities?
Adonisjs's validation system significantly reduces OOB Read risks by ensuring required data exists before your application logic runs. However, it's not a complete solution—you still need defensive programming practices like optional chaining, null checks, and proper error handling for database operations and external data sources.