HIGH command injectionrocketbearer tokens

Command Injection in Rocket with Bearer Tokens

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

Command Injection occurs when an API endpoint passes untrusted input directly to a system shell or process builder. In Rocket, a common pattern is to read an Authorization header containing a Bearer Token and use it as part of a command or script execution flow. Because the token is treated as user-controlled data, an attacker can inject shell metacharacters to alter command behavior.

Consider a Rocket handler that receives a Bearer Token and passes it to a system command without validation:

#[macro_use] extern crate rocket;

use rocket::http::Status;
use rocket::request::Request;

#[get("/run/")]
fn run_command(cmd: String, auth: Option<rocket::http::Header>) -> String {
    if let Some(header) = auth {
        if header.name == "Authorization" {
            let token = header.value.strip_prefix("Bearer ").unwrap_or("");
            // Unsafe: token used directly in command construction
            let output = std::process::Command::new("sh")
                .arg("-c")
                .arg(format!("echo Token: {} && {}", token, cmd))
                .output()
                .expect("failed to execute process");
            return String::from_utf8_lossy(&output.stdout).to_string();
        }
    }
    Status::Unauthorized.into()
}

If an attacker sends cmd as ls and the Bearer Token as mysecret|id, the shell command becomes echo Token: mysecret|id && ls, causing unintended command execution and information disclosure. This is a classic Command Injection vector amplified by the presence of a Bearer Token as uncontrolled input.

Rocket applications often integrate with external services using tokens. When those tokens are forwarded to subprocesses or scripts—such as via std::process::Command, duct, or OS helpers—special characters like ;, &, |, $(), or backticks can change command semantics. Even if the token is obtained from a trusted source (e.g., a header), treating it as safe is a mistake. Attackers can leverage weak input validation or missing allowlists to pivot from authentication context to arbitrary command execution.

Additionally, logging or error messages that include the Bearer Token alongside injected commands can compound risk by exposing sensitive data in logs or responses. The combination of Rocket’s routing and handler flexibility with Bearer Token usage in command construction creates scenarios where injection flaws are subtle yet impactful.

Bearer Tokens-Specific Remediation in Rocket — concrete code fixes

Remediation centers on avoiding shell invocation and strictly validating or encoding any data that may reach the command layer. The safest approach is to bypass the shell entirely and use argument vectors directly.

Instead of using sh -c, use std::process::Command with explicit arguments:

#[macro_use] extern crate rocket;

use rocket::http::Status;
use rocket::request::Request;

#[get("/run/")]
fn run_command_safe(cmd: String, auth: Option<rocket::http::Header>) -> Result<String, Status> {
    if let Some(header) = auth {
        if header.name == "Authorization" {
            if let Some(token) = header.value.strip_prefix("Bearer ") {
                // Validate token format before use (example: alphanumeric + underscores)
                if !token.chars().all(|c| c.is_alphanumeric() || c == '_' || c == '-') {
                    return Err(Status::BadRequest);
                }
                // Safe: no shell, arguments passed directly
                let output = std::process::Command::new("echo")
                    .arg(token)
                    .arg(&cmd)
                    .output()
                    .map_err(|_| Status::InternalServerError)?;
                return Ok(String::from_utf8_lossy(&output.stdout).to_string());
            }
        }
    }
    Err(Status::Unauthorized)
}

This approach eliminates shell injection by not invoking a shell. The token is treated as a literal argument, and a basic allowlist check ensures it does not contain unexpected characters. You can tighten validation further by using regex allowlists or by hashing the token before any external use, ensuring the original token never reaches the command layer.

For Rocket routes that must work with dynamic inputs, prefer structured data flows over string concatenation. If external tooling is required, consider using a controlled wrapper script with strict input sanitization and defined argument boundaries. Logging should redact token values—replace them with a hash or placeholder before writing to any output stream.

Applying these practices aligns with secure handling of Bearer Tokens in Rocket and reduces the attack surface for Command Injection. The key takeaway is to treat all external inputs—including authentication tokens—as untrusted and to avoid passing them through shell interpreters.

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

Can middleBrick detect Command Injection vulnerabilities involving Bearer Tokens in Rocket APIs?
Yes, middleBrick scans unauthenticated attack surfaces and includes checks for input validation and unsafe consumption, which can identify Command Injection risks even when Bearer Tokens are present in request headers.
Does middleBrick test LLM endpoints for prompt injection when Bearer Tokens are used in Rocket integrations?
Yes, the LLM/AI Security checks include active prompt injection testing and system prompt leakage detection, which are applicable when Rocket APIs interact with or expose LLM endpoints using Bearer Token authentication.