In Perl ci sono due sintassi per la costruzione eval:
Caratteristiche della gestione degli errori:
$@ è contenuto il testo dell'errore (se c'è stato un errore), altrimenti $@ è vuoto.eval BLOCK è più veloce, più sicuro e preferibile quando non è necessario eseguire codice dinamico.eval STRING è comodo per la creazione dinamica di codice, ma compila ulteriormente la stringa, risultando più lento e potenzialmente più pericoloso.# Esempio di utilizzo di eval BLOCK my $result = eval { die "Error!" unless 1 + 1 == 2; return "OK"; }; if ($@) { warn "Errore catturato: $@"; } # Esempio di utilizzo di eval STRING my $code = '$x = 1 + 2; $x;'; my $res = eval $code; if ($@) { warn "Errore nella stringa eval: $@"; }
Se si inseriscono variabili dinamiche all'interno di eval STRING senza la dovuta escape, possono sorgere ulteriori rischi?
Sì, se la stringa inserita è formata da variabili, specialmente ottenute da fonti esterne (ad esempio, dall'input dell'utente), si presenta una minaccia di security/injection. È sempre necessario utilizzare l'escape o non utilizzare eval STRING per dati esterni.
my $user_code = 'system("rm -rf /");'; eval $user_code; # MOLTO PERICOLOSO!
Storia
In uno script di audit per il controllo dei parametri delle macchine virtuali, è stato utilizzato eval STRING, nel quale "per errore" venivano inseriti dati letti da un file di configurazione esterno. Un giorno il file è stato sostituito, portando all'esecuzione del codice di un aggressore e alla compromissione del server.
Storia
Lo sviluppatore ha racchiuso una parte di codice potenzialmente pericolosa in eval BLOCK, aspettandosi che
catturassenon solo gli errori di runtime, ma anche quelli di compile-time (ad esempio, errori di sintassi). Tuttavia, l'errore di sintassi (ad esempio, un errore di battitura nel nome di una variabile) non viene intercettato da eval BLOCK — ha causato una terminazione anomala del processo.
Storia
Durante la deserializzazione di strutture dati complesse tramite eval STRING dopo un dump di Dumper, si è dimenticato di verificare che la stringa contenesse solo codice Perl valido — un utente ha aggiunto codice eseguibile tramite input injection, che ha portato all'esecuzione di comandi dannosi sul server.