在Perl中编码时安全地执行系统命令

时间:2012-10-23 04:30:24

标签: perl security

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

3 个答案:

答案 0 :(得分:6)

这取决于在Perl中复制功能的难易程度。如果我需要在某些东西上运行m4宏处理器,我不会想到尝试在Perl中复制该功能,并且因为http://search.cpan.org/上没有看起来合适的模块,所以看起来很合适同意我的观点。那么,在那种情况下,使用外部程序是明智的。另一方面,如果我需要阅读目录的内容,那么Perl中的readdir() et al加stat()lstat()的组合比使用输出的结果更为明智。 ls

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

答案 1 :(得分:2)

执行外部命令可能很昂贵,因为它涉及分配新流程并在需要时观察其输出。

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

Perl非常有能力做很多事情。因此,如果你坚持只使用Perl本机构造和模块来完成你的任务,不仅因为你从不分叉它会更快,但是通过查看返回的本机Perl对象和结构来捕获错误会更加可靠和容易。库例程。当然,它将自动移植到不同的平台。

如果您的脚本在提升的权限下运行(如root或sudo下),那么您应该非常小心执行哪些外部程序。确保基本安全性的一个简单方法是始终按全名指定命令,例如/ usr / bin / grep(但仍然要三思而后,只需通过Perl本身执行grep!)。但是,如果攻击者使用LD_PRELOAD机制注入恶意共享库,即使这可能还不够。

如果您愿意非常安全,建议使用-T标志使用污点检查:

#!/usr/bin/perl -T

如果确定您的脚本具有不同的真实有效用户或组ID,则Perl也会自动启用Taint标志。

在没有Perl抱怨的情况下,污点模式会严重限制你做很多事情(比如system()调用)的能力 - 在http://perldoc.perl.org/perlsec.html#Taint-mode看到更多信息,但它会给你更高的安全性。

答案 2 :(得分:1)

  

在Perl编码时是否应该真正使用外部命令?

这个问题没有一个答案。这完全取决于您在Perl的各种潜在用途中所做的工作。

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

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