W Perlu istnieją dwa składnie konstrukcji eval:
Cechy obsługi błędów:
$@ znajduje się tekst błędu (jeśli błąd wystąpił), w przeciwnym razie $@ jest pusty.eval BLOCK jest szybszy, bezpieczniejszy i preferowany, gdy nie ma potrzeby wykonywania dynamicznego kodu.eval STRING jest wygodny do dynamicznego tworzenia kodu, ale dodatkowo kompiluje ciąg, co jest wolniejsze i potencjalnie bardziej niebezpieczne.# Przykład użycia eval BLOCK my $result = eval { die "Błąd!" unless 1 + 1 == 2; return "OK"; }; if ($@) { warn "Przechwycony błąd: $@"; } # Przykład użycia eval STRING my $code = '$x = 1 + 2; $x;'; my $res = eval $code; if ($@) { warn "Błąd eval string: $@"; }
Czy może wystąpić dodatkowe ryzyko, jeśli dynamicznie podstawiane zmienne w eval STR nie są odpowiednio zabezpieczone?
Tak, jeśli podstawiany ciąg jest formowany z zmiennych, szczególnie uzyskanych z zewnątrz (np. z danych wejściowych użytkownika), istnieje zagrożenie security/injection. Zawsze należy stosować zabezpieczenia lub nie używać eval STRING dla obcych danych.
my $user_code = 'system("rm -rf /");'; eval $user_code; # BARDZO NIEBEZPIECZNE!
Historia
W skrypcie audytowym do sprawdzania parametrów maszyn wirtualnych użyto eval STRING, do którego "przypadkiem" trafiły dane odczytane z zewnętrznego pliku konfiguracyjnego. Pewnego dnia plik został podmieniony, co doprowadziło do wykonania kodu przestępcy i kompromitacji serwera.
Historia
Programista owinął potencjalnie awaryjną część kodu w eval BLOCK, oczekując, że "przechwyci" nie tylko błędy czasu wykonywania, ale i błędy czasu kompilacji (np. błędy składni). Jednak błąd składni (np. literówka w nazwie zmiennej) nie jest przechwytywany przez eval BLOCK — spowodował on awaryjne zakończenie procesu.
Historia
Przy deserializacji złożonych struktur danych przez eval STRING po zrzucie Dumper-a, zapomniano upewnić się, że ciąg zawiera tylko dozwolony kod Perl — użytkownik wykorzystując input injection dodał wykonywalny kod, co doprowadziło do wykonania złośliwych poleceń na serwerze.