Command Injection in Actix with Bearer Tokens
Command Injection in Actix 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 Actix web applications, this risk can be amplified when authorization is handled exclusively via Bearer Tokens and the token or claims derived from it are used to construct commands or file paths. An attacker who can influence a Bearer Token value — for example, by registering a malicious client or through token leakage — may be able to inject shell metacharacters that alter command behavior.
Consider an endpoint that receives a Bearer Token in the Authorization header and uses a claim such as sub to build a system command for user management. If the application does not strictly validate or sanitize the claim, an attacker could supply a token like abc; cat /etc/passwd. When the server concatenates this value into a command, the semicolon causes the shell to execute an additional unintended command, exposing sensitive data. This pattern is especially dangerous when combined with high-privilege process execution or when the Actix runtime is running with elevated operating system permissions.
Another scenario involves file operations where the token is used as part of a filename or directory path. If an attacker controls the token and the application constructs a path like /data/{token}/output.txt, they can use path traversal sequences such as ../../../etc/shadow to access files outside the intended directory. If the application then invokes a system utility using this path, the injected traversal can lead to unauthorized reading or manipulation of sensitive files.
The combination of Actix routing that directly binds headers to handler parameters and insufficient input validation around Bearer Token values creates a clear attack surface. Security checks that focus only on authentication correctness can miss the fact that a trusted token source is being repurposed for command construction. Because middleBrick tests unauthenticated attack surfaces, it can detect endpoints where token-derived inputs flow into command execution logic, highlighting the missing separation between authorization context and system command assembly.
Bearer Tokens-Specific Remediation in Actix — concrete code fixes
To mitigate Command Injection risks when using Bearer Tokens in Actix, ensure that token values and any claims derived from them are never used directly in system commands or file paths. Instead, treat the token as an opaque identifier and map it to a controlled set of permissions or internal identifiers. Use structured data rather than shell commands wherever possible, and apply strict allowlisting for any values that must be passed to external processes.
Below are concrete code examples showing insecure and secure approaches in Actix web applications.
Insecure Example: Token Used in Shell Command
use actix_web::{web, HttpResponse, Responder};
use std::process::Command;
async fn handle_request(auth: web::Header<actix_web::http::header::Authorization<actix_web::http::header::Bearer>>) -> impl Responder {
let token = auth.token();
// Dangerous: using token value directly in command
let output = Command::new("userinfo")
.arg(token)
.output()
.expect("failed to execute process");
HttpResponse::Ok().body(String::from_utf8_lossy(&output.stdout).to_string())
}
Secure Example: Token as Opaque Identifier with Allowlisted Actions
use actix_web::{web, HttpResponse, Responder};
use std::process::Command;
async fn handle_request(auth: web::Header<actix_web::http::header::Authorization<actix_web::http::header::Bearer>>) -> impl Responder {
let token = auth.token();
// Map token to internal user ID using a server-side lookup
let user_id = match lookup_user_by_token(token) {
Some(id) => id,
None => return HttpResponse::Unauthorized().finish(),
};
// Safe: using allowlisted command with numeric user ID
let output = Command::new("userinfo")
.arg("--id")
.arg(user_id.to_string())
.output()
.expect("failed to execute process");
HttpResponse::Ok().body(String::from_utf8_lossy(&output.stdout).to_string())
}
fn lookup_user_by_token(token: &str) -> Option<u32> {
// In practice, validate against a database or cache
match token {
"legit_token_123" => Some(42),
_ => None,
}
}
Additionally, when working with file paths derived from token claims, avoid string concatenation and prefer path-safe APIs that prevent traversal. For example, use Rust’s Path and PathBuf methods to join directories and normalize paths, ensuring that sequences like .. cannot escape the intended base directory.
Another layer of defense is to run backend processes with the least privileges necessary and to avoid invoking shell features that support metacharacters. By combining strict input validation, token-to-identifier mapping, and safe system call patterns, Actix services can neutralize Command Injection risks while still leveraging Bearer Token-based authentication.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |