perl -pe 's/abc/$ARGV[0]/ge'
Are there any security issues in this approach? I mean, is it possible to give a value to a positional parameter that causes perl to perform an undesirable function?
In perldoc perlop in the Regexp Quote-Like Operators section it explains
- e Rate the right side as an expression
- ee Rate the right side as a string, then
eval result.
But it is not so. In both cases, the “right side” —the replacement — is evaluated as if it were a do † block. In the first case, the result provides a replacement string, and in the second, the result is passed to eval , and the result of this provides a replacement string. There is no difference when a replacement is evaluated as an “expression” in the first place and as a “string” in the second.
Both /e and /ee allow any valid Perl code sequence, including loops, conditional expressions, and multiple statements, and are not limited to a single expression
There is nothing wrong with isolation in $ARGV[0] . Thin lines become dangerous only if you execute them like Perl using eval or shell code using system , qx// or backlinks. Thus, in the replacement part of the substitution, one modifier /e works fine
But if you use something else as a replacement, for example
perl -pe 's/abc/qx{$ARGV[0]}/eg'
then this parameter will be executed as a shell command, so it is clearly unsafe. But then not
perl -pe 's/abc/unlink glob "*.*"/eg'
therefore you must be reasonable in this
What is dangerous is the double-e /ee modifier, which treats the replacement as a Perl do block and then performs an eval as a result. So something like
s/abc/$ARGV[0]/eeg
very unsafe because you can run your code as follows
perl -pe 's/abc/$ARGV[0]/eeg' 'unlink glob *.*'
With just one /e this will simply replace abc with the string unlink glob *.* In $ARGV[0] . But using /ee , the line is passed to eval and all your files are deleted!
Remember this:
/ e - replacement is an expression ( do block)
/ ee - the replacement is an expression (a do block), and the result is passed to eval
† This is why I choose to use curly braces to distinguish between permutations that use one of the /e modes. With s{abc}{ $ARGV[0] }ge replacement looks much bigger than a block of code than if I used regular slashes