Security Issues with Perl / e Modifier

Let's say that I have a Perl script that contains a substitution command that takes a replacement string as a positional parameter and uses the /e modifier:

 perl -pe 's/abc/$ARGV[0]/ge;' 

Are there any security issues in this approach? I mean, is it possible to give a positional value to a parameter that causes perl to perform an undesirable function? I mean something similar: perl -pe 's/abc//;unlink ("/tmp/file");' .

+5
source share
2 answers
 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

+6
source

Unlike /ee , there is no risk to /e since it does not invoke the Perl parser. This simply evaluates the code in the source file, just like map BLOCK LIST and for (LIST) BLOCK evaluate their BLOCK .

note that

 s{$foo}{$bar}g 

just short for

 s{$foo}{ qq{$bar} }eg 

So, if you are fine with

 perl -pe's/abc/$ARGV[0]/g' 

then it will be convenient for you

 perl -pe's/abc/"$ARGV[0]"/eg' 

and almost identical

 perl -pe's/abc/$ARGV[0]/eg' 
+1
source

Source: https://habr.com/ru/post/1269455/


All Articles