php安全略谈

用户安全方面:

1、使用常量提高md5安全性
2、Cookie/ Session 少用明文信息
3、Session安全性要大于Cookie
4、使用Cookie/ Session读取信息尽量增加判断信息
5、对于错误信息及时销毁Cookie/ Session
6、阻止用户访问任意目录及其写入权限 重定向 伪静态 htaccess
7、$_POST $_GET $_SESSION 等接受字符及参数并加以过滤 
8、只给PHP web用户很有限的权限(禁root等更高权限)
9、防注入过滤数据库操作常见的关键字
10、对于常用方法加以封装,避免直接暴露SQL语句
11、SSL加密连接数据库
12、用视图(view)、触发器(trigger)或者规则(rule)在数据库层面完成 (权限)
13、创建自己的加密机制,然后把它用在PHP程序内
14、关闭错误报告
15、关闭register_globals=Off

密码+常量 define(常量名称,”值”) 再进行MD5加密 
例:define(ALL_PS,“PHP100”); 
md5(“密码”.ALL_PS);//注册
Md5($_POST[密码].ALL_PS)==数据库密码;//验证 也可以用三目判断

//session防伪造
$_SESSION[“定义的值”]=$数据库读取的值;
$_SESSION[user_shell]=md5(数据库读取的用户名.密码.常量);

//用函数判断放到公共类当中
Function user_shell($uid,$shell){
$sql=mysql_query(“select * from table where ‘uid’=‘$uid’”);
$result=is_array($row=mysql_fetch_array($sql));
$shell=$result?$shell=md5($row[username].$row[password].ALL_PS):false;
If($sell){
return $row;
}else{
echo “你无权限”;
//exit();//到这里终止不再执行
session_destroy();消毁session记录
}

$arr=User_shell($_SESSION[uid],$_SESSION[user_shell]);//调用函数 输出 $arr[username]

SQL注入过程: 

正常来讲,我们通过地址接收一些必要的参数如:

PHP100.php?id=2  页面中我们会使用  2 写入到SQL语句中
 
正常情况:Select * From Table where id=2

如果我们对SQL语句熟悉,就知道2 我们可以替换成我们需要的SQL语句

如:index.php?id=2 and exists (select id from admin) //黑客习用方法

防止注入的几种办法:

其实原来就是我们需要过滤一些我们常见的关键字和符合如:

Select,insert,update,delete,and,*,等等

function inject_check($sql_str) {
$check=eregi('select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile', $sql_str); // 进行过滤
if($check){
echo “输入非法内容”;
exit();
}else{
return $sql_str;
}
}
$_GET[id]= inject_check ($_GET[id]); //使用方法
往下正常写SQL语句

或者是通过系统函数间的过滤特殊符号 addslashes(需要被过滤的内容) 

PHP其他地方安全设置

1、register_globals = Off   设置为关闭状态
2、SQL语句书写时尽量不要省略小引号和单引号---是ESC下面的引号
Select * From Table Where id=2       (不规范)
Select * From `Table` Where `id`=’2’(规范)
3、正确的使用 $_POST $_GET $_SESSION 等接受参数,并加以过滤
4、提高数据库命名技巧,对于一些重要的字段可根据程序特点命名
5、对于常用方法加以封装,避免直接暴露SQL语句

PHP代码安全点滴

初始化你的变量
我们看下面的代码:
if ($admin)
{
echo '登陆成功!';
include('admin.php');
}
else
{
echo '你不是管理员,无法进行管理!';
}
上面的代码好像是能正常运行,没有问题,那么假如提交一个非法的参数过去,那么效果会如何呢?比如我们的这个页是 http://www.traget.com/login.php,
那么我们提交:http://www.target.com/login.php?admin=1,呵呵,你想一想,我们是不是直接就是管理员,可以直接进行管理了?
当然,可能你会觉得不会犯这么简单错的错误,可最近暴出来的phpwind 1.3.6论坛漏洞,导致能够直接拿到管理员权限,就是因为有个$skin变量没有初始化,
导致了后面一系列问题。
那么我们如何避免上面的问题呢?首先,从php.ini入手,把php.ini里面的register_global = off,就是不是所有的注册变量为全局,那么就能避免了。
但是,我们不是服务器管理员,只能从代码上改进了,那么我们如何改进上面的代码呢?我们改写如下:

$admin = 0; // 初始化变量
if ($_POST['admin_user'] && $_POST['admin_pass'])
{
// 判断提交的管理员用户名和密码是不是对的相应的处理代码
// ...
$admin = 1;
}
else
{
$admin = 0;
}

if ($admin)
{
echo '登录成功!';
include('admin.php');
}
else
{
echo '你不是管理员,无法进行管理!';
}
那么这时候你再提交http://www.target.com/login.php?admin=1就不好使了,因为我们在一开始就把变量初始化为 $admin = 0 了,那么你就无法通过这个漏洞获取管理员权限。

防止SQL Injection
SQL注射应该是目前危害最大的攻击方法了,包括最早的ASP到PHP,都是国内这两年流行的技术,
基本原理就是通过对提交变量的不过滤形成注入点然后使恶意用户能够提交一些SQL查询语句,导致重要数据被窃取、数据丢失损坏,或者直接被入侵者拿到后台管理权限。
我们既然了解了基本的注射入侵的方式,那么我们如何去防范呢?这个就应该我们从代码去入手了。
我们知道Web上提交数据有两种方式,一种是GET、一种是POSTT,那么很多常见的SQL注射就是从GET方式入手的,而且注射的语句里面一定包含一些SQL语句,
SQL语句有四大关键词:select、update、delete、insert。如果我们在提交的数据中进行过滤是不是能够避免这些问题呢?
于是我们使用正则就构建如下函数:
/*
函数名称:inject_check()
函数作用:检测提交的值是不是含有SQL注射的字符,防止注射,保护服务器安全
参 数:$sql_str: 提交的变量
返 回 值:返回检测结果,ture or false
函数作者:heiyeluren
*/
function inject_check($sql_str)
{
return eregi('select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile', $sql_str); // 进行过滤
}
函数里把“select,insert,update,delete, union, into, load_file, outfile /*, ./ , ../ , '”等等危险的参数字符串全部过滤掉,那么就能够控制提交的参数了,
程序可以这么构建:
<?php
if (inject_check($_GET['id']))
{
exit('你提交的数据非法,请检查后重新提交!');
}
else
{
$id = $_GET['id'];
echo '提交的数据合法,请继续!';
}
?>
假设我们提交URL为:http://www.target.com/a.php?id=1,那么就会提示:“提交的数据合法,请继续!”。
如果我们提交http://www.target.com/a.php?id=1' select * from tb_name,就会出现提示:“你提交的数据非法,请检查后重新提交!”那么就达到了我们的要求。
但是,问题还没有解决,假如我们提交的是 http://www.target.com/a.php?id=1asdfasdfasdf 呢?这个URL是符合上面的规则的,但是实际上它是不正常的,
于是为了避免可能出现的其它情况,我们可以再构建一个函数来进行检查:

/*
函数名称:verify_id()
函数作用:校验提交的ID类值是否合法
参 数:$id: 提交的ID值
返 回 值:返回处理后的ID
函数作者:heiyeluren
*/
function verify_id($id=null)
{
if (!$id) { exit('没有提交参数!'); } // 是否为空判断
elseif (inject_check($id)) { exit('提交的参数非法!'); } // 注射判断
elseif (!is_numeric($id)) { exit('提交的参数非法!'); } // 数字判断
$id = intval($id); // 整型化
return $id;


<?php
if (inject_check($_GET['id']))
{
exit('你提交的数据非法,请检查后重新提交!');
}
else
{
$id = verify_id($_GET['id']); // 这里引用了我们的过滤函数,对$id进行过滤
echo '提交的数据合法,请继续!';
}
?>

好,问题到这里似乎都解决了,但是我们有没有考虑过Post提交的大批量的数据呢?比如一些字符可能会对数据库造成危害,比如“_”,“%”,这些字符都有特殊意义,
那么我们如果进行控制呢?还有一点,就是当我们的php.ini里面的“magic_quotes_gpc = off”的时候,那么提交的不符合数据库规则的数据都是不会自动在前面加“\”的,
那么我们要控制这些问题,于是构建如下函数:
/*
函数名称:str_check()
函数作用:对提交的字符串进行过滤
参 数:$var: 要处理的字符串
返 回 值:返回过滤后的字符串
函数作者:heiyeluren
*/
function str_check( $str )
{
if (!get_magic_quotes_gpc()) // 判断magic_quotes_gpc是否打开
{
$str = addslashes($str); // 进行过滤
}
$str = str_replace("_", "\_", $str); // 把 '_'过滤掉
$str = str_replace("%", "\%", $str); // 把' % '过滤掉
return $str; 
}
OK,我们又一次的避免了服务器被沦陷的危险。
最后,再考虑提交一些大批量数据的情况,比如发贴,或者写文章、新闻,我们需要一些函数来帮我们过滤和进行转换,再上面函数的基础上,我们构建如下函数:
/*
函数名称:post_check()
函数作用:对提交的编辑内容进行处理
参 数:$post: 要提交的内容
返 回 值:$post: 返回过滤后的内容
函数作者:heiyeluren
*/
function post_check($post)
{
if (!get_magic_quotes_gpc()) // 判断magic_quotes_gpc是否为打开
{
$post = addslashes($post); // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤
}
$post = str_replace("_", "\_", $post); // 把 '_'过滤掉
$post = str_replace("%", "\%", $post); // 把' % '过滤掉
$post = nl2br($post); // 回车转换
$post= htmlspecialchars($post); // html标记转换
return $post;
}
在脚本编程的时候,一定要养成良好的编程习惯,例如本文所说的对变量进行初始化,同时注意变量的过滤,变量对整个系统的安全性起了很重要的作用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值