html5中文学习网

您的位置: 首页 > 网络编程 > PHP编程 » 正文

一步步编写PHP的Framework(十四)_PHP教程_编程技术

[ ] 已经帮助:人解决问题

 LVkHTML5中文学习网 - HTML5先行者学习网

 今天我说一下怎么在框架中over掉这些安全问题。LVkHTML5中文学习网 - HTML5先行者学习网

      首先是SQL注入,这个如果你使用的是PDO,我觉得应该没什么问题,如果你使用的还是mysql_*等API,那么你可以在框架中实现bindParameter或者在插入数据库之前进行字符串转义。LVkHTML5中文学习网 - HTML5先行者学习网

      前两天把上一篇文章写完之后,Vian在后面留言说到过SQL注入的一个解决方案,就是在在插入DB之前进行'''.addslashes($id).''',它的意思就是首先进行addslashes操作,之后再强制单引号包裹,这样它就是一个不折不扣的字符串了,所以就注入不了,我觉得这个方法不错,赞一个!!LVkHTML5中文学习网 - HTML5先行者学习网

      由于SQL注入需要联系到模型,XSS需要联系到视图,这两块儿我都没有开始讲,所以我再后面再讲怎么在框架中解决,当然,如果我写到后面忘记了,你也可以提醒我一下。LVkHTML5中文学习网 - HTML5先行者学习网

      上一次我讲CSRF的时候,并没有给出一个解决方案,今天我就给出这个解决方案。实际上解决的方法很简单,就是给它产生一个随机数,然后后端判定传递过来的数和正确的数是否吻合, 如果不吻合,就不执行相应的代码了,这个随机数我们称为token。LVkHTML5中文学习网 - HTML5先行者学习网

      为了简单,我们就将产生token和得到token的函数都写在控制器中,即Controller.php。LVkHTML5中文学习网 - HTML5先行者学习网

      首先是生成随机数,最简单的方式是使用mt_rand()直接产生一个整数,但在这儿我使用之前我在initphp这个框架中看到的解决csrf的方法,在这儿,也谢谢initphp作者的思路:LVkHTML5中文学习网 - HTML5先行者学习网

      initphp的代码是:LVkHTML5中文学习网 - HTML5先行者学习网

1 private function set_token() {
2         if (!$_COOKIE['init_token']) {
3             $str = substr(md5(time(). $this->get_useragent()), 5, 8);
4             setcookie("init_token", $str, NULL, '/');
5             $_COOKIE['init_token'] = $str; 
6         }
7     }

       为了简单,我这儿就不使用userAgent了,initphp是将当前时间戳和userAgent拼接成字符串之后再md5加密,取出第5到8位,我这边的思路是将当前时间戳进行md5加密,然后从第0位开始取,取得的字符串长度是随机产生的:LVkHTML5中文学习网 - HTML5先行者学习网

1 $token = substr(md5(time()),0,mt_rand(10,15));

      为了防止随机数太大或太小,我设置mt_rand的取值范围为10到15,也就是说产生的token的位数为10到15位。LVkHTML5中文学习网 - HTML5先行者学习网

      生成token之后其他的事情就好办了,当然,首先,也是设置token,我们没有必要每次用户请求的时候都产生一个随机数,所以我们将它存放在COOKIE中,框架载入的时候会判定是否有token,如果没有则动态生成一个,当然,生成的token会在一段时间之后过期失效,我这儿设置的时间为7天。LVkHTML5中文学习网 - HTML5先行者学习网

1 private function _setToken() {
2         if(empty($_COOKIE['_csrfToken'])) {
3             $token = substr(md5(time()),0,mt_rand(10,15));
4             $this->_token = $token;
5             setcookie('_csrfToken',$token,time() + 3600 * 24 * 7);
6         } else {
7             $this->_token = $_COOKIE['_csrfToken'];
8         }
9     }

 LVkHTML5中文学习网 - HTML5先行者学习网

      由于生成token的过程是框架自动完成的,所以没有必要让用户看到此过程,所以将这个函数设为私有,然后在Controller类的构造函数中调用即可。LVkHTML5中文学习网 - HTML5先行者学习网

      刚才是生成token,那么怎么得到token呢,实际上得到token的方法就非常简单了,就是一个简单的getter:LVkHTML5中文学习网 - HTML5先行者学习网

1 protected function _getToken() {
2         return $this->_token;
3     }

      现在我再演示一下在用户编写的控制器的判定过程:LVkHTML5中文学习网 - HTML5先行者学习网

 LVkHTML5中文学习网 - HTML5先行者学习网

       假设用户请求的URL是:http://localhost/index.php?c=Index&a=test&token=rwerdfdsfsdfsLVkHTML5中文学习网 - HTML5先行者学习网

       那么这个控制器的类的代码如下:LVkHTML5中文学习网 - HTML5先行者学习网

01 <?php
02 class IndexController extends Controller {
03     public function test() {
04         $token = empty($_GET['token']) ? '' : $_GET['token'];
05         if($token === $this->_getToken()) {
06             //判定为正常
07         } else {
08             $this->_redirect(array(
09                 //跳转到某一个控制器的某一个Action
10             ));
11         }
12     }
13 }

        可能有人会问URl上面的token值是怎么设置然后传递过来的呢?LVkHTML5中文学习网 - HTML5先行者学习网

        我们可以想一下,假设上一个页面是Index控制器的test2这个Action,那么我们可以在test2这个Action中首先使用$this->_getToken得到token值,然后在将数据传递到视图,视图中使用了之后,用户点击这个链接就可以将这个token值传递过来了。LVkHTML5中文学习网 - HTML5先行者学习网

         我现在提一个问题,假设用户访问A页面的时候得到token,这个token还有两秒就过期了,这个用户三秒之后点击这个含有token的链接到达B页面,B页面由于COOKIE中的token已经失效,所以重新产生一个token,然后再和传递的这个token比较,自然不匹配,然后就跳转了,这还不是有问题的呢,那么怎么解决呢?LVkHTML5中文学习网 - HTML5先行者学习网

         由于还有一点时间,所以我提一下上传文件漏洞吧,用户上传一个比如test.php页面,如果用户没有做文件类型的判定,用户上传这个php文件之后,按照链接访问这个页面,有可能这个页面中有一些破坏性的代码,整个网站就危险了。LVkHTML5中文学习网 - HTML5先行者学习网

          可能你已经在程序中判定了,只允许后缀为jpg,png,gif这三种类型,那么我可以将这个jsp页面后缀改成如jpg,上传成功之后,如果网站存在某种漏洞能够让它修改文件后缀,那么你的网站又危险了!!LVkHTML5中文学习网 - HTML5先行者学习网

          还假设你的网站不允许修改文件后缀名,但是它在上传的图片后面加上一段JS脚本或者在上传的文件名上面写一些脚本,这些都可能很危险!!LVkHTML5中文学习网 - HTML5先行者学习网

LVkHTML5中文学习网 - HTML5先行者学习网
LVkHTML5中文学习网 - HTML5先行者学习网
(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助