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
它解释了
eval
的结果。
但这并不完全正确。在这两种情况下,“右侧”——替换——被评估为好像它是一个do
块†。在第一种情况下,结果提供了替换字符串,而在第二种情况下,结果被传递给eval
,that 的结果提供了替换字符串。 替换首先被评估为“表达式”,其次被评估为“字符串”,这并没有区别。
/e
和 /ee
都允许任何有效的 Perl 代码序列,包括循环、条件和多个语句,并且不限于单个表达式
孤立地使用$ARGV[0]
从来没有任何问题。受污染的字符串只有在您执行它们时才会变得危险,无论是作为 Perl,使用 eval
,还是作为使用 system
、qx//
或反引号的 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 LIST
和for (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 修饰符的安全问题的主要内容,如果未能解决你的问题,请参考以下文章
Java包(访问修饰符的范围)String字符串StringBuilder类基本类型和引用类型