我需要一个非常简单的基于行的(空格分隔的)“语言”,通常会寻找一些预定义的“动作”(第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读取它们)可以构造一些危险的东西?变量扩展的上述方式是否合理安全?或者如果错了,我可以在哪里学习正确的方法? :)
答案 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
之间实际上没有区别。