HIGH command injectionsinatrabearer tokens

Command Injection in Sinatra with Bearer Tokens

Command Injection in Sinatra with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Command Injection occurs when an application passes unsanitized user input to system shell commands. In Sinatra, this risk is amplified when Bearer Token handling logic is coupled with dynamic command construction, because token extraction and validation code may inadvertently pass attacker-controlled data to shell utilities. A typical pattern is reading the Authorization header, extracting the token, and then using it in a subprocess call without proper sanitization, which can allow an attacker to inject shell metacharacters.

Consider a Sinatra endpoint that validates a Bearer token by invoking an external command to inspect token metadata (for example, calling openssl or a custom script). If the token value is concatenated directly into the command string, characters such as semicolons, ampersands, or backticks enable command chaining. For example, a token like abc; cat /etc/passwd could cause the application to execute unintended commands. This becomes a full Command Injection when the runtime environment has access to a shell and the application’s process runs with elevated privileges or accesses sensitive resources.

The combination is particularly dangerous because Bearer Tokens are often treated as opaque strings, but if the application logic uses them in system-level operations (e.g., logging, revocation checks, or integration with external services) via shell commands, it exposes a pathway for attackers to escape the application context. Attack techniques resemble standard Command Injection patterns, such as using &&, ||, or newlines to chain commands. In the context of API security scanning, middleBrick identifies such unsafe consumption by correlating OpenAPI specifications with runtime behavior, flagging endpoints where token-derived input flows into subprocess execution without validation or escaping.

An example vulnerable Sinatra route:

require 'sinatra'
require 'json'

get '/validate' do
  auth = request.env['HTTP_AUTHORIZATION']
  if auth && auth.start_with?('Bearer ')
    token = auth.split(' ').last
    # Unsafe: token used directly in shell command
    result = `openssl enc -d -in token.bin -k #{token}`
    { result: result }.to_json
  else
    status 401
    { error: 'Missing or invalid Authorization header' }.to_json
  end
end

In this snippet, the token extracted from the Bearer header is interpolated into an OpenSSL command. An attacker supplying a token like dummy && id could execute arbitrary commands. middleBrick’s 12 security checks, including Unsafe Consumption and Input Validation, detect this by analyzing the spec-to-runtime data flow and highlighting where uncontrolled input reaches shell-level operations.

Bearer Tokens-Specific Remediation in Sinatra — concrete code fixes

Remediation focuses on eliminating shell command construction entirely or strictly validating and isolating any external invocation. The safest approach is to avoid system commands for token handling and use native Ruby libraries for cryptographic or validation tasks. When external commands are unavoidable, use parameterized execution that bypasses the shell.

First, prefer pure-Ruby validation instead of shelling out. For JWT validation, use a library like jwt to decode and verify signatures without invoking external processes:

require 'sinatra'
require 'json'
require 'jwt'

SECRET_KEY = 'your-secret'

get '/validate' do
  auth = request.env['HTTP_AUTHORIZATION']
  if auth && auth.start_with?('Bearer ')
    token = auth.split(' ').last
    begin
      decoded = JWT.decode(token, SECRET_KEY, true, { algorithm: 'HS256' })
      { valid: true, payload: decoded.first }.to_json
    rescue JWT::DecodeError
      status 401
      { error: 'Invalid token' }.to_json
    end
  else
    status 401
    { error: 'Missing or invalid Authorization header' }.to_json
  end
end

If you must invoke an external binary, avoid shell interpolation by using Open3.capture3 with explicit argument arrays, which prevents the shell from interpreting metacharacters in the token:

require 'sinatra'
require 'json'
require 'open3'

get '/validate' do
  auth = request.env['HTTP_AUTHORIZATION']
  if auth && auth.start_with?('Bearer ')
    token = auth.split(' ').last
    # Safe: arguments passed as array, no shell interpolation
    stdout, stderr, status = Open3.capture3('openssl', 'enc', '-d', '-in', 'token.bin', '-k', token)
    if status.success?
      { result: stdout }.to_json
    else
      status 500
      { error: stderr }.to_json
    end
  else
    status 401
    { error: 'Missing or invalid Authorization header' }.to_json
  end
end

Additionally, enforce strict input validation by whitelisting allowed characters in the token before any processing. Although Bearer tokens are typically base64url-encoded, you can reject tokens containing shell-dangerous characters when they must be used in external contexts:

require 'sinatra'
require 'json'

def safe_token?(token)
  # Allow only base64url-safe characters
  token.match?(\A[a-zA-Z0-9\-_]+\z)
end

get '/validate' do
  auth = request.env['HTTP_AUTHORIZATION']
  if auth && auth.start_with?('Bearer ')
    token = auth.split(' ').last
    unless safe_token?(token)
      status 400
      { error: 'Invalid token format' }.to_json
    end
    # Proceed with safe token usage
    { received: token[0..10] + '...' }.to_json
  else
    status 401
    { error: 'Missing or invalid Authorization header' }.to_json
  end
end

middleBrick’s GitHub Action can be added to CI/CD pipelines to automatically flag endpoints where token-derived input reaches subprocess calls, ensuring that future changes do not reintroduce Unsafe Consumption or improper input handling. The CLI tool also supports scanning these patterns locally during development.

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

Why is interpolating a Bearer token into a shell command unsafe even if the token is short-lived?
Any untrusted data passed to a shell command can enable command chaining via metacharacters. Short-lived tokens do not prevent the injection itself; the risk is in how the input is handled, not its lifetime.
Does using Bearer tokens in query parameters introduce Command Injection risk?
It can if the parameter value is used in shell commands or unvalidated subprocess calls. Query parameters should be treated as untrusted input and never directly interpolated into system commands; use parameterized execution or pure-language libraries instead.