多数大学生出来选择的工作和专业无关
首页 > 专业知识

PHP最主要的安全漏洞有哪些

时间:2017-04-10 16:08:50 [来源]:郑州PHP培训学校

  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 "";
  不用担心用户提供影响你应用程序的输入或是运行输入的服务器,你能安全地使用代码。正则表达式是一个很棒的验证输入的工具。尽管难以掌握它,但在这种情况下是非常有用的。
  你应该总是通过拒绝与你期望数据不相符合的数据,来验证你的用户提供的数据。永远都不要使用在你知道期望数据是有害的情况下仍然接受此数据的方法,此方法是安全漏洞的共同来源。有时,恶意的用户能避开此种方法,例如,用空字符来掩盖坏输入的方法。如此的输入将通过检查,但是它仍然具有坏的影响。
  当你验证任何输入时,你应当尽可能的严格。如果有一些没必要包含的字符,可能的话,你应该要么去除那些无用的字符,要么完全拒绝输入。
  访问控制缺陷
  另一个缺陷,不一定限于PHP应用程序,但仍然是重要的,是访问控制的脆弱性类型。当你的应用程序的某些部分的应用是限定于某些用户的时候,这种缺陷就出现了,如,一个允许更改配置设置或显示敏感信息的管理页面。
  你应该检查每个你的PHP应用程序页面限制加载的用户的访问权利。如果你仅仅只检查在索引页面的用户证书,那么一个恶意的用户能直接进入一个“更深层”网页的链接,这将跳过证书检查的过程。
  如,如果你的网站有攻击用户的可预测IP或固定IP地址,则可以通过限制用户访问该用户的基本IP地址和他们用户的名字在你程序的安全层上是有利的。放置你的受限制的网页在一个由apache.htaccess文件保护的独立的目录里也是一个好的做法。
  将配置文件放置在你web访问目录的外面。一个配置文件包含数据库密码和其他一些能被恶意用户用来渗透或者破坏你站点的信息;从来不让远程用户访问这些文件。使用PHP的include函数来包含这些来自不可web访问的目录的文件,万一这个目录曾因管理员误操作而产生web访问,这可能包括含有“否定一切”的an.htaccess文件。尽管分层安全是多余的,但是它是一件积极的事情。
  对于我的PHP应用程序,我更喜欢基于一下样本的目录结构。所有的功能库,类和配置文件存储在includes目录里。这些include文件总是以a.php扩展名命名,因此即便是跳过所有你的保护,web服务器将解析PHP代码,且不会将它显示给用户。www和管理目录是唯一的目录,它们的文件由一个URL直接被访问,管理目录由an.htaccess文件所保护,这个文件只允许知道用户名和密码的用户进入,且这些密码存储在站点根目录中的.htpasswd文件里。
  /home
  /httpd
  /www.example.com
  .htpasswd
  /includes
  cart.class.php
  config.php
  /logs
  access_log
  error_log
  /www
  index.php
  /admin
  .htaccess
  index.php
  你应该设置你的Apache目录索引到“index.php”,并且在每个目录中保持一个index.php文件。如果不能浏览目录,如一个图片目录或是相似的目录,则设置Apache目录来重定向你的主页。永远都不要通过增加.bak或其他扩展到文件名复制一个php文件在你的公开的web目录里。根据你使用的web服务器(Apache幸而似乎对此服务器有一定保障),此服务器不会解析文件中的PHP代码,可能作为资源输出给碰巧得到拷贝文件URL的用户。如果那个文件包含密码或是其他隐秘信息,此文件将是可读的,如果碰巧给黑客发现,那此文件可能甚至不被Google索引。将文件重命名为a.bak.php的扩展比套接a.bak到.php扩展要更安全,但是最好的解决方法是使用一个源代码版本控制系统比如CVS。尽管CVS学起来很难,但是你花费的时间将在许多方面得到补偿。该系统节省你项目中的每个文件的每个版本,当此后要改变导致的问题时,它能具有无法估量的价值。
 

上一篇:PHP中接收复选框信息的方法

下一篇:php生成随机密码的几种方法