MEDIUM regex dosadonisjs

Regex Dos in Adonisjs

How Regex Dos Manifests in Adonisjs

Regex Denial of Service (ReDoS) in Adonisjs typically occurs when user-controlled input is passed to regular expressions that contain vulnerable patterns. The framework's middleware and validation layers can become attack vectors if not properly configured.

Consider this common Adonisjs controller pattern:

const { validate } = use('Validator')

class UserController {
  async store({ request, response }) {
    const data = request.post()
    
    const rules = {
      email: 'required|email',
      username: 'required|regex:/^[a-zA-Z0-9_]+$/',
      bio: 'regex:/^[\w\s.,!?]+$/'
    }
    
    const validation = await validate(data, rules)
    
    if (validation.fails()) {
      return response.badRequest(validation.messages())
    }
    
    // Process user data
  }
}

The vulnerability emerges when regex patterns contain nested quantifiers or ambiguous constructs. For example, a pattern like a(b|c+)+d can cause exponential backtracking when processing malicious input.

Adonisjs-specific attack vectors include:

  • Route parameter validation using regex patterns in start/routes.js
  • Middleware that validates request headers or query parameters
  • Model query filters that use regex-like syntax
  • Email validation patterns in forms

A practical attack scenario:

// Malicious input targeting vulnerable pattern
const payload = 'a' + 'b'.repeat(1000) + 'c' + 'd'.repeat(1000);

// If controller uses: /^[a-z]+(b|c+)+[d-z]+$/i
// This causes catastrophic backtracking

The framework's default validation often uses regex patterns that, while convenient, can be problematic. The email rule, for instance, uses a complex regex that could theoretically be exploited, though practical exploitation is rare.

Adonisjs-Specific Detection

Detecting ReDoS in Adonisjs applications requires examining both the codebase and runtime behavior. middleBrick's API security scanner can identify vulnerable patterns through static analysis of your application's routes and validation rules.

Code-based detection patterns:

// Look for these patterns in your Adonisjs codebase
const vulnerablePatterns = [
  /(a+)+b/,           // Nested quantifiers
  /(a|aa)+b/,        // Alternating patterns
  /(a*)*/            // Redundant quantifiers
]

// Scan your validation rules
const validationFiles = glob.sync('app/Validators/**/*.js')
validationFiles.forEach(file => {
  const content = fs.readFileSync(file, 'utf8')
  // Parse and analyze regex patterns
})

Runtime detection using middleware:

class SecurityMiddleware {
  async handle({ request, response }, next) {
    const startTime = process.hrtime.bigint()
    
    await next()
    
    const duration = process.hrtime.bigint() - startTime
    
    // Flag requests taking suspiciously long
    if (duration > 100000000n) { // 100ms threshold
      console.warn('Potential ReDoS detected:', {
        url: request.url(),
        duration: Number(duration) / 1000000,
        userAgent: request.header('user-agent')
      })
    }
  }
}

middleBrick specifically scans for:

  • Regex patterns in route definitions
  • Validation rules with potentially vulnerable quantifiers
  • Middleware that processes user input through regex
  • Model query filters using regex-like syntax

The scanner analyzes your Adonisjs application's attack surface without requiring credentials or code access, making it ideal for testing deployed APIs.

Adonisjs-Specific Remediation

Fixing ReDoS in Adonisjs involves both immediate code changes and architectural improvements. Here's how to secure your application:

1. Use possessive quantifiers where supported:

// Instead of: /^[a-z]+(b|c+)+[d-z]+$/i
// Use atomic grouping (if supported) or limit input length
const safePattern = new RegExp('^[a-z]{1,50}(b|c+){1,10}[d-z]{1,50}$', 'i')

// In validation rules
const rules = {
  username: `required|regex:${safePattern.source}`
}

2. Implement input length limits:

class UserController {
  async store({ request, response }) {
    const data = request.post()
    
    // Enforce maximum lengths before regex processing
    if (data.username.length > 50) {
      return response.badRequest({
        error: 'Username exceeds maximum length'
      })
    }
    
    const rules = {
      email: 'required|email|max:100',
      username: 'required|regex:/^[a-zA-Z0-9_]+$/',
      bio: 'regex:/^[\w\s.,!?]{1,500}$/'
    }
    
    // ... rest of validation
  }
}

3. Use safe validation libraries:

const { validate } = use('Validator')

// Create a safe validator instance
const safeValidator = validate.extend('safeRegex', (value, [pattern]) => {
  // Simple length check as first defense
  if (value.length > 200) return false
  
  try {
    const regex = new RegExp(pattern)
    return regex.test(value)
  } catch (error) {
    return false
  }
})

// Use in your controller
const rules = {
  customField: 'required|safeRegex:/^[a-z0-9_-]+$/'
}

4. Implement timeout protection:

class RegexTimeoutMiddleware {
  async handle({ request, response }, next) {
    const timeout = setTimeout(() => {
      return response.status(413).json({
        error: 'Request processing timeout'
      })
    }, 100) // 100ms timeout
    
    await next()
    clearTimeout(timeout)
  }
}

5. Use middleBrick's continuous monitoring to ensure fixes remain effective:

// In your GitHub Actions workflow
- name: Run middleBrick security scan
  uses: middlebrick/middlebrick-action@v1
  with:
    api_url: ${{ secrets.TEST_API_URL }}
    fail_below_score: B
    token: ${{ secrets.MIDDLEBRICK_TOKEN }}
  continue-on-error: true

Remember that ReDoS prevention is about defense in depth: combine input validation, length limits, timeout protection, and regular security scanning to maintain a robust security posture.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

How can I test if my Adonisjs API is vulnerable to Regex DoS?
Use middleBrick's free scanner by submitting your API URL. It will analyze your routes and validation patterns for vulnerable regex constructs. You can also manually test by sending crafted payloads with nested patterns to your endpoints and monitoring response times.
Does Adonisjs provide built-in protection against ReDoS?
Adonisjs doesn't have specific ReDoS protection built-in. The framework relies on developer awareness and proper input validation. However, you can implement middleware-based timeouts and use safe validation patterns to mitigate risks.