2012-10-23 39 views
2

在Perl中编写代码时应该真的使用外部命令吗?我看到它的几个缺点。它不是系统独立的,加上安全风险也可能存在。你怎么看?如果没有办法,并且必须使用Perl的shell命令,那么执行该特定命令的最安全方法是什么(如检查pid,uid等)?在Perl中编码时安全地执行系统命令

回答

6

这取决于在Perl中复制功能的难度。如果我需要运行m4宏处理器,我不想尝试在Perl中自己复制该功能,并且因为http://search.cpan.org/上没有模块,所以看起来合适,但其他人会同意我的看法。那样的话,使用外部程序是明智的。另一方面,如果我需要读取目录的内容,那么Perl内部的readdir()等加上stat()lstat()的组合比打开ls的输出更合理。

如果您需要执行命令,请仔细考虑如何调用它们。特别是,您可能希望避免shell解释参数,因此请使用system(另请参阅exec)等数组形式,而不是命令加参数的单个字符串(这意味着shell用于处理命令线)。

2

执行外部命令的代价可能很高,因为它涉及分叉新进程并在需要时监视其输出。

可能更重要的是,如果外部过程因任何原因失败,可能很难通过脚本理解发生了什么。更糟糕的是,令人惊讶的是,外部过程经常会永久停留,所以会是你的脚本。你可以使用特殊的技巧,例如打开管道和在循环中观察输出,但是这本身很容易出错。

Perl能够做很多事情。因此,如果您坚持只使用Perl本机构造和模块来完成您的任务,不仅因为您永远不会分叉,速度会更快,而且通过查看返回的本地Perl对象和结构来捕获错误更可靠,更容易库例程。当然,它会自动移植到不同的平台上。

如果您的脚本在提升的权限下运行(如root或sudo下),您应该非常小心执行哪些外部程序。确保基本安全性的一个简单方法是始终使用全名来指定命令,例如/ usr/bin/grep(但仍然会考虑两次,并且仅由Perl本身执行grep!)。但是,如果攻击者正在使用LD_PRELOAD机制注入恶意共享库,这甚至可能不够。

如果你愿意去很安全,建议使用-T标志像这样使用受污染的检查:

#!/usr/bin/perl -T 

污点标志将被Perl也自动启用,如果你的脚本被确定有不同的真实和有效的用户或组ID。

受感染的模式将严重限制您在没有Perl抱怨的情况下执行许多事情(如system()调用)的能力 - 请参阅http://perldoc.perl.org/perlsec.html#Taint-mode更多内容,但它会为您提供更高的安全性。

+0

是污染模式会更加严格和安全的方式。 –

1

应该在Perl中编码时真的使用外部命令吗?

这个问题没有单一的答案。这完全取决于您在Perl的广泛潜在用途中所做的事情。

你是否在你的本地机器上使用Perl作为美化的shell脚本,或者只是试图为你的问题找到一个快速而又脏的解决方案?在这种情况下,如果这是完成任务的最简单方法,那么运行系统命令就很有意义。安全性和速度并不那么重要。重要的是快速编码的能力。

另一方面,你在写一个生产程序吗?在这种情况下,您需要安全,便携,高效的代码。通常最好在Perl中编写功能(或使用模块),而不是调用外部程序。至少,你应该认真思考好处和缺点。