变量替换/扩展 - perl中的安全方式

时间:2013-05-07 12:17:13

标签: perl code-injection substitution

我需要一个非常简单的基于行的(空格分隔的)“语言”,通常会寻找一些预定义的“动作”(第1个字段),并使用参数执行定义的perl subs(行中的其他字段)

许多行动中的一个是“定义变量值”,在下一个行动中应该可以使用什么。

代码片段(输入在 DATA 中):

use 5.012;
use strict;
use warnings;
use Data::Dumper;

my $VARS;
while(my $line = <DATA>) {
    chomp $line;
    next unless ($line =~ m/^\s*(def|echo|SOME|OTHER|ACTIONS|HERE)\s+(.*)/ );
    my $action = $1;
    my $args = $2;
    my(@fld) = split /\s+/, $args;
    for ($action) {
        when (/^def$/) { $VARS->{$fld[0]} = expandvars($fld[1]); } #expand and store
        when (/^echo$/) { say expandvars($args); }  #echo
    }
    #say Dumper($VARS);
}

sub expandvars {
    my($str) = @_;
    if( $str =~ /\$\{(\w+?)\}/ ) {
        ##############################################
        #is this SAFE or Dangerous? 
        $str =~ s/\$\{(\w+?)\}/$VARS->{$1}/xeg;
        ##############################################
    }
    return $str;
}
__DATA__
#"action" define aaa
def aaa somestring

#define bbb
def bbb ===${aaa}===

#echo 
echo this is ${bbb} here

#here will continue another "actions", but they're
#not needed for the question

该程序正在运行(可能远离“最佳”),给出了想要的结果

this is ===somestring=== here

但我的问题是:

我是如何用变量 SAFE 代替的?那么,如果用户将给出一些其他行(程序将从stdin读取它们)可以构造一些危险的东西?变量扩展的上述方式是否合理安全?或者如果错了,我可以在哪里学习正确的方法? :)

2 个答案:

答案 0 :(得分:1)

攻击者必须将字符放在括号中或打开新字符。如果你把它缩小到单词字符,我不知道它是如何不安全的。

顺便说一句,您可以通过使捕获表达式为变量名称为+来加速正则表达式。如果你遇到一个近似卷曲,你就不会在指定\w的情况下使用它。

s/\$\{(\w+)\}/$VARS->{$1}/xeg;

答案 1 :(得分:1)

您的代码是安全的,因为我无法看到注入攻击。但是,这不是一个特别精心设计的模板语言:

def .   invisible
def var no-vars-with spaces
echo ${.}
echo ${var}

应输出

${.}
no-vars-with

您的代码可能会被更好地考虑,但这在很大程度上是无关紧要的。

您的替换上的/e标记在这种情况下不执行任何操作:qq/$var/$var之间实际上没有区别。