Perl /e 修饰符的安全问题

Posted

技术标签:

【中文标题】Perl /e 修饰符的安全问题【英文标题】:security concerns with Perl /e modifier 【发布时间】:2017-07-03 22:34:41 【问题描述】:

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

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

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

【问题讨论】:

可能dup,但不确定。我从来没有使用过e 正则表达式修饰符,以至于我需要担心它。有效的问题。 【参考方案1】:
perl -pe 's/abc/$ARGV[0]/ge'

这种方法是否存在任何安全问题?我的意思是是否有可能给出这样的位置参数值导致 perl 执行不需要的功能?


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

e 将右侧计算为表达式 ee 将右侧计算为字符串,然后计算eval 的结果。

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

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

孤立地使用$ARGV[0] 从来没有任何问题。受污染的字符串只有在您执行它们时才会变得危险,无论是作为 Perl,使用 eval,还是作为使用 systemqx// 或反引号的 shell 代码。所以在替换的替换部分用一个/e修饰符就可以了

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

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

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

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

所以你必须对此保持理智

什么是危险的 是双 e 修饰符 /ee,它将替换视为 Perl 的 do 块,然后在结果。所以像

    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 模式之一的替换。与 sabc $ARGV[0] ge 替换看起来更像是代码块,而不是我使用通常的斜线

【讨论】:

“但这并不完全正确” 这是误导性的,值得报告一个错误,所以当我回到正常工作的 PC 时我会发布一个。我目前在雅典的一家酒店里,笔记本电脑没电了,没有充电器,只有我的平板电脑可以与世界交谈!【参考方案2】:

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

注意

s$foo$barg

只是简写

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'

【讨论】:

以上是关于Perl /e 修饰符的安全问题的主要内容,如果未能解决你的问题,请参考以下文章

在perl中使用变量作为正则表达式修饰符[重复]

Java包(访问修饰符的范围)String字符串StringBuilder类基本类型和引用类型

iOS中atomic修饰符的底层实现

编程笔试中不会的问题

超硬核:深入讲解Perl安全之代码审计——perl脚本中存在的问题与存在的安全风险

java修饰符