flawopen.com/command-injection/Rust

● CWE-918 · Critique
Recherche · FlawOpen

Command Injection in Rust

Learn how to fix Command Injection (CWE-78) in Rust. Side-by-side vulnerable vs secure code examples for std::process::Command with isolated argument slices.

💡 Explication en Langage Simple (ELI5)

Imaginez demander à un assistant de bureau d'imprimer un document nommé 'rapport.pdf'. L'injection de commande se produit lorsque quelqu'un fournit le nom 'rapport.pdf; whoami', et l'assistant transmet aveuglément le billet au terminal, imprimant le rapport et lisant le badge d'administrateur.

Concepts Clés et Termes

Web Application Security
Composant d'architecture clé affecté par CWE-918.
CWE-918
Classification standard Common Weakness Enumeration (CWE) pour command-injection-rust.
Defense-in-Depth
Vérification d'ingénierie multicouche et isolation des limites à l'exécution.

Déroulement de l'Attaque Étape par Étape

Step 1

Ingestion de Paramètres Non Fiables

L'application reçoit des noms d'hôte de diagnostic ou des noms de fichiers directement à partir d'une requête HTTP.

Step 2

Interpolation Shell Non Sécurisée

Le backend assemble une commande shell par simple concaténation de chaînes au lieu d'utiliser un tableau d'arguments isolé.

Step 3

Injection de Séparateur de Commandes

L'attaquant injecte des métacaractères shell comme ';', '&&', '|' ou des accents graves (ex. '127.0.0.1; id') pour échapper au contexte initial.

Step 4

Exécution en Sous-shell et Compromission

Le shell du système d'exploitation exécute la commande injectée avec tous les privilèges du processus du serveur web.

Code Source : Vulnérable vs Sécurisé

✕ IMPLÉMENTATION VULNÉRABLE
// Spawning shell explicitly with format! string
use std::process::Command;

fn run_backup(folder: &str) {
    // Attacker input: "data; whoami"
    let cmd = format!("tar -czf backup.tar.gz {}", folder);
    Command::new("sh")
        .arg("-c")
        .arg(&cmd)
        .status()
        .expect("failed");
}
✓ PATCH SÉCURISÉ ET ROBUSTE
// Calling binary directly with discrete .arg() calls
use std::process::Command;

fn run_backup(folder: &str) {
    // folder is passed as a literal argument to tar, not shell
    Command::new("tar")
        .arg("-czf")
        .arg("backup.tar.gz")
        .arg(folder)
        .status()
        .expect("failed");
}

Liste de Contrôle de Sécurité pour l'Ingénierie

References