HIGH shellshockadonisjsapi keys

Shellshock in Adonisjs with Api Keys

Shellshock in Adonisjs with Api Keys — how this specific combination creates or exposes the vulnerability

Shellshock (CVE-2014-6271 and related variants) is a command injection vulnerability in the Bash shell that arises when function exports are passed to subprocesses. While AdonisJS is a Node.js framework and does not invoke Bash directly, a typical AdonisJS service can still be exposed to Shellshock-style issues when it constructs and executes shell commands using unchecked inputs. If your AdonisJS application exposes endpoints that invoke system utilities (for example, to process files, generate reports, or interact with legacy tooling) and those endpoints rely on API keys for access control, improper handling of those keys and other parameters can introduce injection paths.

Consider an endpoint that accepts an API key as a header and then uses parts of that key or associated metadata in a shell command. For instance, a developer might log or tag operations by embedding the API key or a derived value into a command string. If the API key contains characters that are not strictly validated or sanitized—such as spaces, semicolons, or shell metacharacters—an attacker could craft a key or an input derived from the key to execute arbitrary commands. This becomes a Shellshock-like vector when the runtime environment invokes a shell to run the command, allowing injected code to run with the same privileges as the application.

Another scenario involves environment variables and subprocess spawning. AdonisJS applications often rely on environment configuration. If an API key is stored in or read from environment variables and later used in a shell invocation without proper escaping, the injected content can alter the command syntax. For example, a value like abc; rm -rf / could cause unintended command execution if passed through an unsafe exec or child_process call. Even when the API key itself is not directly injected, related parameters such as usernames, tenant identifiers, or request IDs that are concatenated into shell commands can become the injection point.

In the context of the middleBrick security scanner, checks for Input Validation, Authentication (via API keys), and Unsafe Consumption are triggered during a scan of an AdonisJS endpoint that uses API keys in this manner. The scanner tests whether malformed or malicious API keys lead to command injection or unexpected behavior, and whether outputs expose sensitive data or error details that aid further exploitation. This is especially important when OpenAPI specifications define security schemes using API keys but do not enforce strict input constraints on key values used in runtime command construction.

Api Keys-Specific Remediation in Adonisjs — concrete code fixes

Remediation centers on strict validation, avoiding shell invasions for API-key-derived values, and using safe process management when shell interaction is unavoidable. Below are concrete patterns and code examples for AdonisJS.

1. Validate and sanitize API keys before any use

Treat API keys as opaque strings and validate their format strictly. Do not embed them in commands or logs in a way that allows shell interpretation.

import { schema } from '@ioc:Adonis/Core/Validator'

const apiKeySchema = schema.create({
  api_key: schema.string({}, [
    (value) => /^[A-Za-z0-9\-_]+$/.test(value) || 'api_key contains invalid characters',
  ]),
})

export const validateApiKey = async (ctx: HttpContextContract) => {
  const payload = await ctx.validate(apiKeySchema)
  // payload.api_key is now safe to use as a string identifier
  return payload.api_key
}

2. Use environment variables and configuration, not dynamic shell commands

Avoid constructing shell commands that include API keys or any user-influenced values. Instead, use AdonisJS configuration and environment variables to manage secrets and invoke utilities safely.

import Env from '@ioc:Adonis/Core/Env'
import { execFile } from 'child_process'
import { promisify } from 'util'

const execFileAsync = promisify(execFile)

export async function runSafeTool(input: string) {
  const allowedInput = input.replace(/[^\w\-\.]/g, '')
  const { stdout, stderr } = await execFileAsync(Env.get('SAFE_TOOL_PATH', '/usr/bin/safe-tool'), [
    '--input', allowedInput,
    '--config', Env.get('TOOL_CONFIG', '/etc/tool/config.yaml'),
  ])
  return { stdout, stderr }
}

3. If shell invocation is required, escape rigorously or use structured APIs

If you must invoke a shell, use parameterized arguments or a shell-escaping library, and never concatenate raw API keys into the command string.

import { exec } from 'child_process'
import escape from 'shell-escape'

export function runWithShell(apiKey: string, file: string) {
  // Escape all dynamic values; treat apiKey as data, not code
  const command = escape(['/usr/bin/process', '--key', apiKey, '--file', file])
  return new Promise((resolve, reject) => {
    exec(command, (error, stdout, stderr) => {
      if (error) return reject(error)
      resolve({ stdout, stderr })
    })
  })
}

4. Do not log raw API keys or echo them in responses

Ensure logging mechanisms redact or hash API keys. This reduces the risk that log injection contributes to a Shellshock-like chain or information disclosure.

import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export function safeLogging(ctx: HttpContextContract, apiKey: string) {
  const hashedKey = require('crypto').createHash('sha256').update(apiKey).digest('hex')
  ctx.logger.info('API request processed', { api_key_hash: hashedKey })
}

5. Apply middleware to enforce key format and reject suspicious values

Use AdonisJS middleware to reject API keys with dangerous characters before they reach command-building logic.

import { Exception } from '@poppinss/utils'

export const validateKeyMiddleware = (ctx: HttpContextContract, next: () => Promise) => {
  const apiKey = ctx.request.header('x-api-key')
  if (!apiKey || !/^[A-Za-z0-9\-_=]+$/.test(apiKey)) {
    throw new Exception('Invalid API key format', 400, 'E_INVALID_KEY')
  }
  return next()
}

Frequently Asked Questions

How does middleBrick detect Shellshock-related risks in an AdonisJS API that uses API keys?
middleBrick runs parallel security checks including Input Validation, Authentication (API keys), and Unsafe Consumption. It submits unauthenticated requests with crafted API keys and inspects outputs for command injection indicators, exposed errors, or PII in responses, then reports findings with severity and remediation guidance.
What should I do if my OpenAPI spec defines API key security but my AdonisJS endpoint still executes shell commands?
Treat the spec as a design reference and align implementation: validate and treat API keys as opaque strings, avoid concatenating them into shell commands, use execFile over shell execution, and apply strict input sanitization. Use the middleBrick CLI to scan your endpoint and verify that no dangerous patterns remain.