flawopen.com/command-injection/Rust

● CWE-918 · Kritis
Riset Keamanan · 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.

💡 Penjelasan Sederhana (ELI5)

Bayangkan meminta asisten kantor untuk mencetak dokumen bernama 'laporan.pdf'. Injeksi perintah terjadi saat seseorang memberikan nama 'laporan.pdf; whoami', dan asisten menyerahkan seluruh catatan tersebut ke terminal loket, mencetak dokumen sekaligus membaca lencana administrator.

Konsep Kunci & Istilah

Web Application Security
Komponen arsitektur utama yang terpengaruh oleh CWE-918.
CWE-918
Klasifikasi standar Common Weakness Enumeration (CWE) untuk command-injection-rust.
Defense-in-Depth
Verifikasi rekayasa berlapis dan isolasi batas waktu proses (runtime).

Alur Serangan Langkah demi Langkah

Step 1

Penerimaan Parameter Tidak Tepercaya

Aplikasi menerima input nama host diagnostik atau nama file langsung dari permintaan HTTP.

Step 2

Penggabungan String Shell Tidak Aman

Backend merangkai perintah shell menggunakan penggabungan string mentah alih-alih vektor argumen terisolasi.

Step 3

Injeksi Pemisah Perintah

Penyerang menyisipkan karakter meta shell seperti ';', '&&', '|', atau backticks (misal: '127.0.0.1; id') untuk keluar dari konteks perintah.

Step 4

Eksekusi Subshell & Kompromi Host

Shell sistem operasi menjalankan perintah yang disuntikkan dengan hak akses penuh proses web server.

Kode Sumber: Rentan vs Aman

✕ IMPLEMENTASI RENTAN
// 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");
}
✓ PERBAIKAN AMAN & KUAT
// 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");
}

Daftar Periksa Penguatan Sistem Rekayasa

References