Perl/e修饰符的安全性问题

Mar*_*tin 5 security perl

假设我有一个Perl脚本,其中包含一个替换命令,它将替换字符串作为位置参数并使用/e修饰符:

perl -pe 's/abc/$ARGV[0]/ge;'
Run Code Online (Sandbox Code Playgroud)

这种方法是否存在安全问题?我的意思是可以给出这样的位置参数值,使perl执行不需要的功能吗?我的意思是类似的:perl -pe 's/abc//;unlink ("/tmp/file");'.

Bor*_*din 6

perl -pe 's/abc/$ARGV[0]/ge'
Run Code Online (Sandbox Code Playgroud)

这种方法是否存在安全问题?我的意思是可以给出这样的位置参数值,使perl执行不需要的功能吗?


perldoc perlop 一节中的 正则表达式报价样运营商 它解释

  • e评估右侧作为表达
  • ee将右侧评估为字符串,然后评估eval结果.

但这并非完全正确.在这两种情况下,"右侧" - 替换 - 被评估为好像是do.在第一种情况下,结果提供了替换字符串,而在第二个的结果被传递到eval和的结果的是提供替换字符串.没有任何区别,其中替换被首先评估为"表达"并且在第二个中被评估为"字符串".

二者/e/ee允许任何有效的Perl代码序列,包括循环,条件,和多个语句,并且不限于单个表达

$ARGV[0]隔离从来没有任何问题.受污染的字符串成为唯一的,如果你危险的执行它们,要么像Perl,使用eval,或作为shell代码使用system,qx//或反引号.因此,在使用单个/e修饰符进行替换的替换部分中,这很好

但是,如果您在替换中使用其他东西,例如

perl -pe 's/abc/qx{$ARGV[0]}/eg'
Run Code Online (Sandbox Code Playgroud)

然后该参数将作为shell命令执行,因此显然不安全.但当时也不是

perl -pe 's/abc/unlink glob "*.*"/eg'
Run Code Online (Sandbox Code Playgroud)

所以你必须明白它

什么是危险的是double-e修饰符/ee,它将替换作为Perldo块处理,然后eval对结果进行处理.所以像

    s/abc/$ARGV[0]/eeg
Run Code Online (Sandbox Code Playgroud)

是非常不安全的,因为你可以像这样运行你的代码

    perl -pe 's/abc/$ARGV[0]/eeg' 'unlink glob *.*'
Run Code Online (Sandbox Code Playgroud)

只是一个单一的/e,这将只替换abc字符串 unlink glob *.*$ARGV[0].但是使用/ee,传递的字符串eval将删除所有文件!

记住这一点:

  • / e - 替换是表达式(do块)

  • / ee - replacement是一个表达式(一个do块),结果传递给eval



这就是为什么我选择使用大括号来界定使用其中一种/e模式的替换.随着 s{abc}{ $ARGV[0] }ge 更换看起来更像代码块,这是比我曾用通常的斜杠