[label][PHP-Security]PHP Security Program

本文是通过阅读http://www.nowamagic.net/中的PHP安全变成专题,同时结合个人的一点点开发经验组合而成的。

如果你需要看原文,可以直接访问http://www.nowamagic.net/进去看原文,写的很好,第一次你看不懂的话,建议你看第二次,文章的质量都很高。

PHP通过超级全局数组如$_GET, $_POST, 及$_COOKIE清楚地表示了用户数据的来源。一个严格的命名体系能保证你在程序代码的任何部分知道所有数据的来源,这也是我一直所示范和强调的。

1. register_globals,公用变量会自动建立 , 当register_globals开启时,任何使用未初始化变量的行为几乎就意味着安全漏洞。这个是php.ini配置文件中的一个设置,该设置在PHP5.3.0版本就已经不建议开启使用,并且在PHP5.4.0版本中已经被移除掉;

在php.ini中将register_globals设置为on之后,那么就可以往你的PHP脚本注入(inject)各种各样的变量,例如:来自HTML表单form的各种变量-get传参和post传参。

综上所述(this couple with the fact  that......),当PHP不需要变量的初始化意味着会更加容易写安全性低下的代码。

这是一个艰难的选择,但是PHP社区决定将register_globals默认设置为不开启(disable)。打开的时候,大家使用变量时无法确定它们来自于哪里,只能猜测假设。

脚本内部自己定义的变量将会和用户发送的请求数据混乱在一起,但是我们可以通过禁用(disable)register_globals来改变这个问题。

让我们通过一个滥用register_globals例子来做展示:

<?php
//Example #1 Example misuse with register_globals = on

//define $authorized = true only if user is authenticated

if(authenticated_user()){
 $authorized = true;
}
// Because we didn‘t first initialize $authorized as false, this might be// defined through register_globals, like for GET auth.php?authorized=1// So, anyone can be seen as authenticated!if($authorized){  include "hightly/sensitive/data.php";}
?>

最好的代码就是,在使用一个变量之前,我们必须要先声明,在上面的代码中,我们可以应该首先将$authorized = false ,这样子无论register_globals on or off都已经会影响到我们的代码。

因为即使通过GET auth.php?authorized=1也影响不到我们的默认设置$authorized = false 。

<?php
//Example #2 Example use of sessions with register_globals on or off

//We wouldn‘t knoe where $username came from but to know $_SESSION
// is for session data , so We can use $_SESSION

if(isset($_SESSION[‘username‘])){
    echo ‘hello <b>{$_SESSION[‘username‘]}</b>‘;
}else{
    echo ‘hello Guest‘;
    echo ‘Would you like to login?‘;
}

?>

2.不要暴露数据库访问权限

假设db.inc为数据库的用户名和密码配置文件,解决方案有:

1)使用Apache的rewrite module,拒绝对.inc资源的请求。

  <Files ~ "\.inc$">

    Order allow,deny

    Deny from all

  </Files>

2)可以将db.inc改名为db.inc.php,这样子即使访问到该脚本,也不会产生输出,从而不会被看到。

3)直接将该配置文件保存在网站根目录以为的包含目录中,注意应该要让服务器具有对该文件的读取权限,这样子就不会有可以访问到这个文件的URL。

注意:所有位于网站根目录下的资源都有相应的URL,如果Apache中没有定义对.inc等等后缀的文件的处理方式类型,那么在对这一类文件进行访问是,会以普通文件的类型进行返回(默认类型),这样子文件内容就会暴露。

3.错误显示配置

<?php
//设置报错级别,关闭错误显示,错误日志记录开启,错误日志记录保存路径
  ini_set(‘error_reporting‘ , E_ALL | E_STRICT);

  ini_set(‘display_errors‘ , ‘off‘);

  ini_set(‘log_errors‘ , ‘on‘); // Start error logging

  ini_set(‘error_log‘ , ‘/usr/local/apache/logs/error_log‘); //Saving path

//通过set_error_handler()函数来设置自己的错误处理函数 , mixed set_error_handler(callable $error_handler [,int $error_types = E_ALL | E_STRICT])

   set_error_handler(‘my_error_handler‘);    

   function my_error_handler(......){......}
?>

4.过滤用户输入: 识别输入,过滤输入,区分已过滤及被污染数据

输入是指所有源自外部的数据。例如,所有发自客户端的是输入,但客户端并不是唯一的外部数据源,其他如数据库和RSS推送等也是外部数据源。

PHP中,就是使用$_GET和$_POST这两个超级公用数组来存放用户输入数据。

$_SEVER数组中的很多元素是用客户端所操纵的,难以确认哪些元素组成了输入,最好的方法是把整个数组看成输入。最好也把$_SESSION和数据库也看成为输入来处理。

<?php
//防止跨目录

//Example #1
$file_name = $_POST[‘name‘];

str_replace( ‘..‘  , ‘.‘  , $file_name);
//这种做法是造成了其他漏洞的,当输入有3个以上点的时候,那么则一样会发生目录跳转

$file_name_2 = ‘.../.../etc/passwd‘;

echo str_replace( ‘..‘ , ‘.‘ ,$file_name_2); //输出结果为: ../../etc/passwd

//要想杜绝出现上面这种跨目录访问的情况,那么应该使用循环一直到没有‘..‘
$file_name_3 = $_POST[‘name‘];

while(strpos($file_name_3 , ‘..‘) !== false){//只要还存在跳转目录,那么就一直代替

   $file_name_3 = str_replace(‘..‘ , ‘.‘ , $file_name_3);
}
?>
<?php
//好心办坏事的问题,那就是任何试图纠正非法数据的举动都可能斗志潜在错误并允许非法数据通过

//试图纠正非法数据的行为是错误的,只做一个更安全的检查才是更加安全的选择

//例子:客户希望用户名前后有空格则不能登录,结果修改时对用户登录程序进行了更改
//用trim()函数把输入的用户名前后的空格去掉了(这就是纠正非法数据的行为),同时
//在注册时还是允许前后有空格,这是一个很明显的问题

//register
 if(strpos($_POST[‘register_name‘] , ‘ ‘)){ //strpos(),如果有查找的字符,那么就返回该字符的位置,没有则返回false
    echo ‘username can not have space!‘;
}else{

   echo ‘register success.‘;
}

//login

if(strpost($_POST[‘login_name‘] , ‘ ‘)){

   echo ‘Invalid username.‘;
}else{

   echo ‘login success.‘;
}
?>

1. trim()

NotePossible gotcha: removing middle characters

Because trim() trims characters from the beginning and end of a string, it may be confusing when characters are (or are not) removed from the middle. trim(‘abc‘, ‘bad‘) removes both ‘a‘ and ‘b‘ because it trims ‘a‘ thus moving ‘b‘ to the beginning to also be trimmed. So, this is why it "works" whereas trim(‘abc‘, ‘b‘) seemingly does not.

http://hk2.php.net/manual/en/function.trim.php

2. ctype_alnum()

bool ctype_alnum ( string $text )

Checks if all of the characters in the provided stringtext, are alphanumeric.

http://hk2.php.net/manual/en/function.ctype-alnum.php

除了把过滤作为一个检查过程之外,还可以使用白名单方法——假定检查的数据是非法的,除非能证明是合法的。

最后一步是使用一个命名约定或其他方法来区分已过滤的数据和被污染的数据。

一个简单的方法就是,把所有已经过滤了的数据存放入一个叫$clean的变量中,同时使用两个步骤来防止被污染数据的注入:

1)经常初始化$clean为一个空数组;

2)加入检查及阻止来自外部数据源的变量名为clean。

举个例子:

<form action="process.php" method="post">
Please select a color:
  <select name="color">
     <option value="red">red</option>
     <option value="green">green</option>
     <option value="blue">nlue</option>
  </select>
<input type="submit" name="submit" />
</form>  

<?php
//过滤数据
// 初始化为一个空数组,防止包含被污染的数据,一旦证明$_POST[‘color‘]是red,green,blue中的一个是,就保存到$clean[‘color‘]变量中。
$clean = array();
switch($_POST[‘color‘]){

 case ‘red‘:
 case ‘green‘:
 case ‘blue‘:
   $clean[‘color‘] = $_POST[‘color‘];
   break;
}

?>

上面的这个例子对于过来一组已知的合法值的数据很有效,但是对于过滤一组由某些已知的合法字符组成的数据,那就没有什么帮助了。

例如:需要一个只能是由字母及数字组成的用户名

<?php
$clean = array();

if(ctype_alnum($_POST[‘username‘])){

 $clean[‘username‘] = $_POST[‘username‘];
}

?>

5.转义,针对两面:一方面是针对客户端的输出一定要转义;一方面是针对参与数据库操作的数据一定要转义

5.1对客户端的输出进行转义

<?php

 $html = array(); //初始化为一个空数组,防止包含污染数据
 $html[‘username‘] = htmlentities($clean[‘username‘] , ENT_QUOTES , ‘UTF-8‘);// htmlspecialchars()
//引号转义的方式(第二参数),应该指定为ENT_QUOTES,转义单引号和双引号//字符集(第三参数),字符集参数必须要和页面所使用的字符集想匹配
echo $html[‘username‘];

?>

5.2对参与数据库操作的数据进行转义

<?php

$mysql = array();
$mysql[‘username‘] = mysql_real_escape_string($clean[‘username‘]);
$sql = "SELECT *
           FROM profile
           WHERE username = ‘{$mysql[‘username‘]}‘";
$result = mysql_query($sql);

?>

6.用户传送数据的方式:

6.1通过URL(如GET传送数据方式)

如果你在GET方式提交的表单中的action中试图使用请求串,它会被表单中的数据取代。

如果你指定了一个非常的请求方式,或者请求方式没有写,浏览器默认以GET方式提交数据。

6.2通过一个请求的内容(如POST数据方式)

6.3通过HTTP头部信息(如cookie)

7.URL语义攻击

8.

时间: 2024-08-27 11:06:53

[label][PHP-Security]PHP Security Program的相关文章

Spring Security: Spring Security简介

Spring Security简介 安全领域的两大核心是:Authentication和Authorization . ·Authentication是身份认证,把控一个系统的入口. ·Authorization是授权,用于进行系统中功能的访问控制. Spring Security 为J2EE项目提供了一个综合的解决方案,支持Authentication和Authorization. Spring Security对于Authentication提供了很宽泛的支持.集成了多种认证技术: HTTP

Spring Security 之security.xml详解

简单说明一下springsecurity的原理(此段摘自网络) 1.AccessDecisionManager 和我们一般实现登录验证采用filter的方式一样,springsecurity也是一个过滤器,当请求被springsecurity拦截后,会先对用户请求的资源进行安全认证,如果用户有权访问该资源,则放行,否则将阻断用户请求或提供用户登录,在springsecurity中,负责对用户的请求资源进行安全认证的是AccessDecisionManager,它就是一组投票器的集合,默认的策略是

Cross-Domain Security For Data Vault

Cross-domain security for data vault is described. At least one database is accessible from a plurality of network domains, each network domain having a domain security level. The at least one database includes at least one partitioned data table tha

Linux LSM(Linux Security Modules) Hook Technology(undone)

目录 0. 引言 1. Linux Security Module Framework Introduction 2. LSM Sourcecode Analysis 3. LSMs Hook Engine:基于LSM Hook进行元数据的监控获取 4. LSM编程示例 0. 引言 从最佳实践的角度来说,在Linux Kernel中进行安全审计.Access Control(访问控制)最好的方式就是使用Linux提供的原生的框架机制,例如 1. Kprobe: Linux提供的原生的调试机制(D

Spring Security入门Demo

一.spring Security简介 SpringSecurity,这是一种基于Spring AOP和Servlet过滤器的安全框架.它提供全面的安全性解决方案,同时在Web请求级和方法调用级处理身份确认和授权.在Spring Framework基础上,Spring Security充分利用了依赖注入(DI,Dependency Injection)和面向切面技术. 二.建立工程 参考http://blog.csdn.net/haishu_zheng/article/details/51490

Understanding and Using HRMS Security in Oracle HRMS

Understanding and Using HRMS Security in Oracle HRMS Product:Oracle Human Resources Minimum Version:11.5.9 An Oracle White Paper Abstract Document History Author : Steve Cooper Create Date : 04-OCT-2006 Last Update Date : 18-JUN-2008 Expiration Date

java Permissions and Security Policy--官方文档

3 Permissions and Security Policy 3.1 The Permission Classes The permission classes represent access to system resources. The java.security.Permission class is an abstract class and is subclassed, as appropriate, to represent specific accesses. As an

CISSP AIO 2th: Information Security Governance and Risk Management

2.11 Security Steering Committee(安全指导委员会) A security steering committee is responsible for making decisions on tactical and strategic security issues within the enterprise as a whole and should not be tied to one or more business units. The group sho

用spring security实现简单的登陆和权限角色控制

 随笔简介 spring版本:4.3.2.RELEASE+spring security 版本:4.1.2.RELEASE(其它不做说明) 所展示内容全部用注解配置 springmvc已经配置好,不作说明 会涉及到springmvc,spel,el的东西,不熟悉的同学可以先去看一下这方面内容,特别是springmvc 首先想一下,登陆需要什么,最简单的情况下,用户名,密码,然后比对数据库,如果吻合就跳转到个人页面,否则回到登陆页面,并且提示用户名密码错误.这个过程中应该还带有权限角色,并且贯穿整

[转]Spring Security学习总结一

[总结-含源码]Spring Security学习总结一(补命名空间配置) Posted on 2008-08-20 10:25 tangtb 阅读(43111) 评论(27)  编辑  收藏 所属分类: Spring .Spring Security Spring Security学习总结一 在认识Spring Security之前,所有的权限验证逻辑都混杂在业务逻辑中,用户的每个操作以前可能都需要对用户是否有进行该项 操作的权限进行判断,来达到认证授权的目的.类似这样的权限验证逻辑代码被分散