[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()Note: Possible 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 string,
text
, 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.
[label][PHP-Security]PHP Security Program的更多相关文章
- [spring security] spring security 4 基础Demo
依赖包: <properties> <junit.version>4.11</junit.version> <spring.version>4.1.6. ...
- [Security] Web Security Essentials
In this course, we'll learn how to exploit and then mitigate several common Web Security Vulnerabili ...
- spring security method security
参考 Spring Security 官方文档 http://www.concretepage.com/spring/spring-security/preauthorize-postauthoriz ...
- 【JavaEE】SSH+Spring Security自定义Security的部分处理策略
本文建立在 SSH与Spring Security整合 一文的基础上,从这篇文章的example上做修改,或者从 配置了AOP 的example上做修改皆可.这里主要补充我在实际使用Spring Se ...
- Spring boot Security Disable security
When I use security.basic.enabled=false to disable security on a Spring Boot project that has the fo ...
- Linux LSM(Linux Security Modules) Hook Technology
目录 . 引言 . Linux Security Module Framework Introduction . LSM Sourcecode Analysis . LSMs Hook Engine: ...
- Cross-Domain Security For Data Vault
Cross-domain security for data vault is described. At least one database is accessible from a plural ...
- 【Spring】关于Boot应用中集成Spring Security你必须了解的那些事
Spring Security Spring Security是Spring社区的一个顶级项目,也是Spring Boot官方推荐使用的Security框架.除了常规的Authentication和A ...
- java Permissions and Security Policy--官方文档
3 Permissions and Security Policy 3.1 The Permission Classes The permission classes represent access ...
- spring security 3中的10个典型用法小结
spring security 3比较庞大,但功能很强,下面小结下spring security 3中值得 注意的10个典型用法 1)多个authentication-provide可以同时使用 &l ...
随机推荐
- Unicode化
为了程序编写方便,根除乱码问题等等需求,很多新项目都采用了Unicode编码.同时,不少使用MBCS多字节编码的旧项目为了升级,也有了转向Unicode编码的意向.不过,从MBCS升级到Unicode ...
- EF-CodeFirst系列100
.学习资料地址: CodeFirst:https://msdn.microsoft.com/zh-cn/data/jj193542 一.CodeFirst迁移(Migration) .工具--> ...
- RecordingOptions录制设置选项
1.录制思考时间 2.录制方式 3.自定义证书 4.非资源选项
- [转]oracle 12c 中的分页子句
转自:http://blog.itpub.net/271063/viewspace-1061279/ -- 连接数据库 创建测试用户-- Connected to Oracle Database 12 ...
- python socket 详细介绍
Python 提供了两个基本的 socket 模块. 第一个是 Socket,它提供了标准的 BSD Sockets API. 第二个是 SocketServer, 它提供了服务器中心类,可以简化网络 ...
- ZOJ-3230-Solving the Problems
/*ZOJ Problem Set - 3230Solving the Problems ------------------------------------------------------- ...
- --- no python application found, check your startup logs for errors
--- no python application found, check your startup logs for errors 碰到这个问题,请留意下系统执行的python版本和自己的djan ...
- mybatis 学习五 二级缓存不推荐使用
mybatis 二级缓存不推荐使用 一 mybatis的缓存使用. 大体就是首先根据你的sqlid,参数的信息自己算出一个key值,然后你查询的时候,会先把这个key值去缓存中找看有没有value,如 ...
- Pthreads 环境配置,VisualStudio
▶ Visual Studio 下配置MPI环境 ● 下载 Pthreads(http://pthreads.org/),解压. ● 针对 x64 程序的配置 ■ 将 Pre-built.2\incl ...
- C# JSON 序列化
1.JavaScriptSerializer System.Web.Extensions.dll System.Web.Script.Serialization命名空间 Serialize Deser ...