background image

PHP 最主要的 个安全漏洞

对于快速发展的动态网页而言,PHP 是一种了不起的语言。PHP 也具有对初级程序员友好的特点,比如
PHP 就不需要动态声明。然而,这些特征可能导致一个程序员无意地让安全漏洞潜入到 web 应用程序中。
在 PHP 应用中,流行的安全邮件列表就出现大量被证实的漏洞,但是一旦你明白 PHP 应用程序中常见
的几种漏洞的基本类型,那你将发现它和其他语言是同样安全的。
  在这篇文章中,我将详细地介绍会导致安全漏洞的几种常用见的 PHP 程序缺陷。通过向你们展示什
么是不能做的,并且如何利用每个特定的缺陷,我希望你们不仅仅能明白怎样避免这些特定的缺陷,而
且为什么这些错误能导致安全漏洞。
  明白每个可能出现的缺陷,将帮助你们避免在 PHP 应用程序中产生同样的错误。
  安全是一个过程,不是一个产品在应用程序开发过程中采用对安全有益的方法可以让你生成更紧密,
更健壮的代码。
  未校验输入缺陷
  如果不是最常见的 PHP 安全漏洞,也是其中之一的,就是未校验输入错误。提供数据的用户是根本
不能信任的。你应该假定你的 web 应用程序的用户个个都是心怀叵测的,因为他们中的一些就是那样的。
未校验或不正确验证输入是被一些漏洞所利用的根源,我们将在本文后面进行讨论。
  例如,你可能写一个允许用户查看日历的如下代码,通过调用 UNIX 的 cal 命令来显示指定月份。
  $month = $_GET['month'];
  $year = $_GET['year'];
  exec("cal $month $year", $result);
  print "
"; 
  foreach ($result as $r) { print "$r"; }
  print "";
 
  此代码具有一个安全漏洞缝隙,因为没有以任何的方式来验证$_GET[month]和$_GET[year]变量。
只要那个特定的月份是在 1 到 12 之间,并且提供一个合适的四位数年份,那这个应用程序将完美运行 。
然而,恶意用户可能追加“; ls - la”到年参数,从而看到您网站的 HTML 目录列表。一个极端恶劣的用户
可能追加";rm -rf *"到年参数,且删除整个网站!
  纠正这种错误的合适的方法就是确保你从用户接受的输入是你期望得到的。不用为这种错误使用

JavaScript 验证,创造他们自己形式 javascript 或是禁用 javascript 的开发者是很容易处理如此的验
证方法的。为确保输入月份和年份是数字,且只有数字,你需要添加 PHP 代码,如下所示。
  $month = $_GET['month'];
  $year = $_GET['year'];
  if (!preg_match("/^[0-9]{1,2}$/", $month)) die("Bad month, please re-enter.");
  if (!preg_match("/^[0-9]{4}$/", $year)) die("Bad year, please re-enter.");
  exec("cal $month $year", $result);
  print "
"; 
  foreach ($result as $r) { print "$r"; }
  print "";
 
  不用担心用户提供影响你应用程序的输入或是运行输入的服务器,你能安全地使用代码。正则表达
式是一个很棒的验证输入的工具。尽管难以掌握它,但在这种情况下是非常有用的。
  你应该总是通过拒绝与你期望数据不相符合的数据,来验证你的用户提供的数据。永远都不要使用