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

时间:2017-07-03 22:34:41

标签: perl security

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

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

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

2 个答案:

答案 0 :(得分:6)

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

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

perldoc perlop 在该部分 Regexp Quote-Like Operators 它解释了

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

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

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

孤立$ARGV[0]从来没有任何问题。只有当您执行它们时,受污染的字符串才会变得危险,无论是使用eval还是使用system,还是使用qx///e或反引号作为shell代码。因此,使用单个perl -pe 's/abc/qx{$ARGV[0]}/eg' 修饰符进行替换的替换部分很好

但如果您在替换中使用其他内容,例如

perl -pe 's/abc/unlink glob "*.*"/eg'

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

/ee

所以你必须明白它

什么是危险的 是double-e修饰符do,它将替换视为Perl eval块,然后执行{ {1}}结果。像

这样的东西
    s/abc/$ARGV[0]/eeg

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

    perl -pe 's/abc/$ARGV[0]/eeg' 'unlink glob *.*'

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

记住这一点:

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

  • / ee - 替换是表达式do阻止),结果传递给 eval



这就是为什么我选择使用大括号来分隔使用/e模式之一的替换。随着 s{abc}{ $ARGV[0] }ge 替换看起来更像是代码块,而不是我使用了常用的斜杠

答案 1 :(得分:2)

/ee不同,/e没有固有的风险,因为它没有调用Perl解析器。它只会导致评估源文件中的代码,就像map BLOCK LISTfor (LIST) BLOCK评估其BLOCK的方式一样。

请注意

s{$foo}{$bar}g

只是

的简称
s{$foo}{ qq{$bar} }eg

所以,如果您对

感到满意
perl -pe's/abc/$ARGV[0]/g'

然后你就可以了

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

和几乎相同的

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