In Perl, there are two syntaxes for the eval construction:
Error handling features:
$@ contains the error message (if an error occurred), otherwise $@ is empty.eval BLOCK is faster, safer, and preferable when dynamic code execution is not required.eval STRING is convenient for dynamic code creation but additionally compiles the string, making it slower and potentially more dangerous.# Example of using eval BLOCK my $result = eval { die "Error!" unless 1 + 1 == 2; return "OK"; }; if ($@) { warn "Error caught: $@"; } # Example of using eval STRING my $code = '$x = 1 + 2; $x;'; my $res = eval $code; if ($@) { warn "Eval string error: $@"; }
If dynamically inserted variables are placed inside eval STRING without proper escaping, can additional risks arise?
Yes, if the inserted string is constructed from variables, especially those obtained from external sources (e.g., user input), there is a threat of security/injection. Always use escaping or avoid using eval STRING for external data.
my $user_code = 'system("rm -rf /");'; eval $user_code; # VERY DANGEROUS!
Story
In an auditing script used to check virtual machine parameters, eval STRING was used, and it "accidentally" included data read from an external configuration file. One day the file was replaced, leading to the execution of the attacker's code and server compromise.
Story
A developer wrapped a potentially crashing part of the code in eval BLOCK, expecting it to "catch" not only runtime errors but also compile-time errors (e.g., syntax errors). However, a syntax error (e.g., a typo in a variable name) is not caught by eval BLOCK — it caused the process to crash.
Story
When deserializing complex data structures via eval STRING after a Dumper dump, it was forgotten to ensure that the string contained only valid Perl code — a user used input injection to add executable code, resulting in the execution of malicious commands on the server.