本文和大家重点讨论一下Perl脚本中的一些安全问题,几乎每一种编程语言都有一定这样的漏洞,这种漏洞将会在某种程度上导致不安全软件的产生,Perl也有它安全上令人担忧的部分,然而大多数程序员完全没有意识到这些方面。
Perl脚本中的一些安全问题
对一种编程语言而言,在设计这种语言的时候,一般是不会产生安全隐患的,事实上,这种隐患是由程序员引入的。几乎每一种编程语言都有一定这样的漏洞,这种漏洞将会在某种程度上导致不安全软件的产生,但是一个如软件整体的安全性仍然大部分依赖于这个软件制造者的知识面、理解能力和他的安全意识。Perl也有它安全上令人担忧的部分,然而大多数程序员完全没有意识到这些方面。
在这篇文章里,我们将会看一下Perl中一些最普遍被误用和忽视的属性。我们将会看到它们的误用将会怎样对运行它们的系统的安全以及它们的用户造成威胁。我们将会演示怎样把这些弱点挖掘出来以及如何去修改、避免它们。
用户输入上的弱点
Perl脚本中产生安全问题的一个很大的来源是没有经过正确确认(或根本就没有确认)的用户的输入。每次当你的程序要从一个不信任用户那里获取输入信息的时候,即使采用的是非直接的方式,你都应该小心。举个例子来说吧,如果你在Perl中写CGI脚本,你要预期到恶意的用户将会发送给你假的输入。不正确的用户输入,如果没有经过确认就被认可并使用了,将会导致许多方面出错。最常见和明显的错误是,没有经过确认就去执行有用户自定义参数的其他程序。
syetem()和exec()函数
Perl脚本以能被用作一种“粘合”语言而著称——它能够通过如下方式完成一个出色的工作:在调用其他程序来为它工作的时候,通过采集一个程序的输出,将它重新格式成一种特定的方式后传递到其他程序的输入的方式仔细的协调它们的运行。这样各个程序就能很好的运行了。
正如Perl发布标语告许我们的,我们有不止一种方法可以做同样的事。一种执行一个外部程序和一个系统命令的方法事通过调用exec()函数。当Perl遇到一个exec()语句的时候,它审视exec()被调用处的参数,然后启动一个新的进程来执行这条特定的命令。Perl脚本从不会返回控制给调用exec()的原来的那个进程。
另一个相似的函数是system()。system()的运行方式非常象exec()。它们之间的唯一的大的区别是Perl会首先从父进程中分叉出一个子进程,子进程作为提供给system()的一个参数。父进程等到子进程结束运行后再接着运行程序的其余部分。我们将会在下面更详细的讨论system()调用,但这些讨论大部分也适用于exec()。
传递给system()的参数是一个列表——列表里的第一个元素是要被执行的这个程序的程序名,其他元素是传给这个程序的参数。然而,如果只有一个参数的的话,system()的执行方式会发生差异。在那种情形下,Perl将会扫描这个参数看它是不是包含任何shell转换字符。如果有的话,它就要把这些字符通过shell来解释。所以产生一个shell命令行来工作。不然,Perl会降字符串拆成单词然后调用效率更高的c库函数execvp(),这个函数不能理解特殊的shell字符。
现在假设我们有一张CGI表单,它要询问用户名,然后显示包含这个用户统计信息的一个文件。我名可以如下使用system()来调用’cat’实现那种要求:
system("cat/usr/stats/$username");
用户名来自这样的一个表单:
$username=param("username");
.举个例子,当用户在表单里添上username=jdimov,然后提交后。Perl在字符串``cat/usr/stats/jdimov中没有找到任何转换字符创,所以它就调用execvp()函数运行”cat”后返回到我们的脚本中。这个Perl脚本也许看起来没有害处可言,但是它容易被一个恶意的攻击者所利用。
【编辑推荐】