Shellshock in Adonisjs with Mutual Tls
Shellshock in Adonisjs with Mutual Tls — how this specific combination creates or exposes the vulnerability
Shellshock (CVE-2014-6271, CVE-2014-7169) is a command injection vulnerability in the Bourne Again Shell (bash) where crafted environment variables cause unintended code execution. In AdonisJS, which is a Node.js framework, Shellshock is not a direct framework flaw, but an environmental risk that surfaces through insecure server or build configurations and external tooling. When mutual TLS (mTLS) is used, the interaction between secure transport and runtime environment setup can inadvertently expose or amplify Shellshock-related risk.
mTLS requires both the client and server to present valid certificates during the TLS handshake. In AdonisJS, this typically involves configuring an HTTPS server with request certificate verification. While mTLS strengthens authentication and prevents man-in-the-middle attacks, it does not protect against command injection introduced through the environment. If the Node.js process or associated tooling (such as native addons, build scripts, or reverse proxies like nginx) uses bash in a way that passes unsanitized input into environment variables, Shellshock can be triggered even when mTLS is enforced.
A concrete scenario: an AdonisJS service running behind a reverse proxy that terminates mTLS may forward client certificate details (e.g., the Common Name) into environment variables or CGI-like contexts for logging or request tagging. If these values are later used in a bash invocation—such as generating audit entries, invoking shell-based build steps, or calling native modules that spawn bash—attackers can inject malicious payloads via specially crafted certificate fields. This makes the combination of Shellshock and mTLS particularly dangerous: mTLS may give a false sense of security while the underlying shell remains exploitable through environmental vectors.
Real-world patterns include using bash in npm lifecycle scripts that export certificate metadata, or invoking shell commands from within AdonisJS providers to handle certificate pinning checks. If user-influenced data (e.g., certificate fields parsed from the mTLS handshake) flows into these shell invocations without strict validation, it can lead to arbitrary command execution. The vulnerability is not in AdonisJS itself but in how the runtime environment and tooling handle bash and environment variables when mTLS is active.
Detection involves inspecting how certificate data is handled. For example, if an AdonisJS app exports SSL_CLIENT_S_DN_CN (from mTLS) into the environment and later uses it in a shell command, this creates a direct injection path. The middleBrick LLM/AI Security checks and unauthenticated scanning can help surface risky patterns by analyzing runtime behavior and spec-defined endpoints, even when mTLS is in place.
Remediation focuses on eliminating bash usage for processing untrusted data, validating and sanitizing all certificate-derived inputs, and avoiding environment-based code execution. Do not rely on mTLS alone to prevent injection; treat certificate metadata as untrusted input. Use structured logging and Node.js-native crypto utilities instead of shell invocations for certificate handling.
Mutual Tls-Specific Remediation in Adonisjs — concrete code fixes
To secure AdonisJS with mTLS while mitigating Shellshock risks, ensure certificate data is never passed into shell environments or bash scripts. Use Node.js-native TLS options and strict input handling. Below are concrete configurations and code examples.
First, configure the AdonisJS HTTPS server with proper mTLS options in start/server.ts:
import { HttpServer } from '@adonisjs/core'
import { join } from 'path'
export const server = HttpServer.make((config) => {
config.https = {
key: join(__dirname, '../cert/server.key'),
cert: join(__dirname, '../cert/server.crt'),
ca: join(__dirname, '../cert/ca.crt'),
requestCert: true,
rejectUnauthorized: true,
}
})
This enforces mTLS by requiring client certificates and rejecting unauthorized connections. Note that this configuration does not automatically sanitize environment variables derived from certificate fields.
Second, avoid exporting certificate metadata into environment variables. Instead, handle certificate details directly in Node.js. For example, read the client certificate from the request object and validate it using Node’s crypto module:
import { createSecureContext } from 'tls'
import { HttpServer } from '@adonisjs/core'
export const server = HttpServer.make((config) => {
config.https = {
key: join(__dirname, '../cert/server.key'),
cert: join(__dirname, '../cert/server.crt'),
ca: join(__dirname, '../cert/ca.crt'),
requestCert: true,
rejectUnauthorized: true,
secureContextMiddleware: (ctx) => {
const cert = ctx.socket.getPeerCertificate()
if (cert) {
// Validate certificate fields directly in Node.js
const commonName = cert.subject.CN
if (!isValidCommonName(commonName)) {
ctx.respond('Unauthorized', 401)
}
}
},
}
})
function isValidCommonName(cn: string): boolean {
// Implement strict allowlist validation
const allowed = ['trusted-client.example.com']
return allowed.includes(cn)
}
Third, if you must use environment variables for operational reasons, sanitize inputs rigorously and avoid bash. For instance, if you need to pass certificate fingerprints to a logging script, use Node.js child_process with explicit argument arrays instead of shell strings:
import { execFile } from 'child_process'
import { join } from 'path'
execFile('logger-script', [certFingerprint], (err, stdout, stderr) => {
if (err) console.error(err)
})
Never do this:
// UNSAFE: passes unsanitized input to bash
const env = { CN: process.env.SSL_CLIENT_S_DN_CN }
exec(`echo ${env.CN}`, (err, stdout) => { /* ... */ })
Finally, audit dependencies and build pipelines for bash usage. Even if AdonisJS itself does not invoke bash, npm scripts or native modules might. Use middleBrick’s CLI to scan your API and verify that no unsafe shell invocations are present in the runtime or build chain. The dashboard and GitHub Action integrations can help enforce secure configurations as part of CI/CD gates.