Fuzzing di programmi Rust
Il fuzzing è una tecnica di testing dinamica che consiste nel fornire input casuali o non validi a un programma al fine di individuare bug, crash o vulnerabilità di sicurezza. In Rust, possiamo sfruttare lo strumento cargo-fuzz per eseguire il fuzzing dei nostri programmi in modo efficace e automatizzato.
Configurazione di cargo-fuzz
Per utilizzare cargo-fuzz, è necessario aggiungere cargo-fuzz come dipendenza nel file Cargo.toml del progetto:
[dependencies]
fuzz_targets = "0.2"
[dev-dependencies]
cargo-fuzz = "0.11"
Creiamo quindi una cartella fuzz nella radice del progetto e all'interno un file fuzz/Cargo.toml:
[package]
name = "fuzz"
version = "0.1.0"
edition = "2021"
[dependencies]
fuzz_targets = "0.2"
Definizione di un target di fuzzing
Successivamente, definiamo un target di fuzzing nel file fuzz/fuzz_targets/parse.rs, in questo esempio stiamo cercando di capire se il parsing di un i32 da una stringa può dare problemi.
#![allow(unused)] #![no_main] fn main() { use libfuzzer_sys::fuzz_target; // Questa funzione è il nostro target di fuzzing fuzz_target!(|data: &[u8]| { // Convertiamo l'input in una stringa UTF-8 if let Ok(s) = std::str::from_utf8(data) { // Eseguiamo il parsing della stringa let _ = s.parse::<i32>(); } }); }
Esecuzione del Fuzzing
Per eseguire il fuzzing, possiamo utilizzare il comando cargo fuzz run parse:
$ cargo fuzz run parse
Durante l'esecuzione, cargo-fuzz genera automaticamente input casuali per testare la funzione di parsing. Ogni volta che viene trovato un input che provoca un fallimento, cargo-fuzz conserva quel caso di test per ulteriori analisi.
cargo-fuzz produce inoltre report dettagliati che mostrano gli input che hanno causato crash o errori nel programma sotto test. Questi report sono essenziali per comprendere e risolvere le vulnerabilità o i bug identificati durante il fuzzing.
Tramite il fuzzing in Rust è possibile:
- Identificare precocemente di Bug: il fuzzing permette di individuare bug e vulnerabilità di sicurezza che potrebbero non essere stati previsti durante lo sviluppo.
- Automatizzare il Testing:
cargo-fuzzautomatizza il processo di generazione e test di input casuali, riducendo l'onere manuale sullo sviluppatore. - Migliorare la Sicurezza: migliorando la copertura dei test, il fuzzing contribuisce a garantire che il software sia robusto e sicuro anche in presenza di input non previsti.