我正在尝试使用污点模式。我想根据用户输入打开一个文件并打开一个文件来读取数据。以下是我的代码
#!/usr/bin/perl -w
use strict;
use warnings;
my $name = $ARGV[0];
my $file = "/Desktop/data/$name";
open MYFILE, "$file" or die $!;
while (<MYFILE>) {
chomp;
print "$_\n";
}
close(MYFILE);
案例1)当我使用文件运行时 perl -w filename.pl input.txt 我能够从文件中读取数据。
案例2)当我改变
时#!/usr/bin/perl -w
to
#!/usr/bin/perl -T
并使用运行该文件 perl -T filename.pl input.txt 我仍然能够阅读数据。
案例3)当我在写入模式下将文件更改为打开并在污染模式下运行时,我得到正确的输出,
Insecure dependency in open while running with -t switch at test1.pl line 8.
案例二可能会出现什么问题?或者这是正确的行为吗?
是否允许以污点模式打开文件进行阅读?
答案 0 :(得分:4)
对于污点模式,这是正确的行为。 The documentation指定:
您不得使用从程序外部派生的数据来影响程序之外的其他内容 - 至少不是偶然的。
[...]
$arg = shift; # $arg is tainted
[...]
如果你试图做一些不安全的事情,你会收到类似“不安全依赖”或“不安全$ ENV {PATH}”之类的致命错误。
(编辑:错过了一些东西):
在任何调用子shell的命令中,也不能在任何修改文件,目录或进程的命令中直接或间接使用受污染的数据,但以下情况除外:
- 不检查打印和syswrite的参数是否有污点。
(这就是读模式示例不会抱怨文件数据的原因。)
命令行参数可能不安全,因此在被指定之前会被污染。
确定数据是否受到污染:
要测试变量是否包含污染数据,并且其使用会因此触发“不安全依赖”消息,您可以使用Scalar :: Util模块的tainted()函数,该函数可在附近的CPAN镜像中使用,并包含在内在Perl中从5.8.0版本开始。
取消数据:
[...]绕过污点机制的唯一方法是从正则表达式匹配引用子模式。 Perl假定如果使用
$1
,$2
等引用子字符串,那么在编写模式时就知道自己在做什么。这意味着使用一点思考 - 不要盲目地解开任何事情,或者你打败整个机制。最好验证变量只有好字符(对于某些“好”值),而不是检查它是否有任何坏字符。那是因为很容易错过你从未想过的坏人物。
(警告use locale
):
如果您正在编写可识别区域设置的程序,并希望使用包含
\w
的正则表达式清洗数据,请将no locale
放在同一块中的表达式之前。有关进一步的讨论和示例,请参阅SECURITY in perllocale。
答案 1 :(得分:1)
这可以防止以下内容擦除您的硬盘:
perl script.pl '| rm -rf /'
解决方案:使用仅接受文件名的open
形式。
open(my $fh, '<', $ARGV[0])