上次讲到控制器怎么样将数据传递到视图,今天我就主要说一下在程序中怎么让代码更“安全”,以后就转到讲模型,再讲怎么作视图,最后再讲控制器的功能强化。 php
我再声明一下,我写这个文章只是让你们对PHP的框架编写有一个基本的了解,因为本人技术有限,这个文章是给PHP初学者学习的,因此高手勿喷,还有就是我如今时间也有限,因此每次可能须要两三天才能写一篇,每篇我写的时间也要控制在一个小时之内,因为边写这个文章边编代码,因此代码中可能会存在不少BUG,见谅!! mysql
若是你是一个PHP爱好者,请在文章后面积极回复一下,这种交流不只可使个人PHP技术提升,也鼓励了我继续写下去的勇气,谢谢!! linux
不少人编写PHP代码什么都不注意,遇到不少警告,就直接经过error_reporting屏蔽掉,这样作我以为问题是很是大的,好比: sql
<?php $a = $_GET['a'];
echo $a;若是经过GET方式传递的参数有a,那么程序很是正常,可是若是没有传递呢,那就会抛出一个警告!!
个人做法是首先将error_reporting设置为E_STRICT,不容许程序出现警告!! 数据库
刚才这段代码可能就须要修改为: 编程
<?php $a = isset($_GET['a']) ? $_GET['a'] : '';
echo $a;除了这种问题,还有就是PHP特有的 @符号 ,不少人都喜欢用这个来屏蔽错误,可是我以为使用这个弊大于利,由于当项目很大的时候,出现一个错误,因为这个错误又被屏蔽,要找到这个错误的位置真心的很难!!
关于异常的处理,虽然try catch会带来很大的开销,我我的以为为了程序的健壮性,必要的try catch仍是须要的。 安全
好吧,杂七杂八的说了这么多,貌似这个和安全不太沾得上边,但对于我来讲,它们也是“安全”的一部分。 服务器
如今假设你花费了十天时间编写了一个简单的博客系统,购买了万网的虚拟主机或VPS,申请域名,网站备案,而后部署代码,这一切的一切都搞定了,而后用户就能够经过好比www.test.com这样一个域名来访问你的博客系统,你这套博客系统很受欢迎,短期内就积累了大量的人气,可是忽然有一天,你发现你的网站忽然出故障了,你怎么办? session
在线上将PHP的配置文件中的error_reporting打开,而后线上调试? 框架
说实话,我以前也在个人博客系统上面线上调试过,和上述状况不同的一点是,个人博客访问量很低,由于我这我的太懒了,不太喜欢去管理个人博客。
若是你的网站拥有很大的访问量,你在线上作调试想一想也是不可能的事情,那怎么作呢?
记Log,若是你的网站在发生故障以前你就有写Log,那么程序出现故障以后你只须要打开日志文件,而后就能够看到故障出现的位置,而后修复掉,这样就OK了!!
好了,现假设我是你的同窗,而且也参与了你的博客系统的开发,可是我和你前一阵闹了一点矛盾,我怀恨在心,想把你的博客系统破坏掉,怎么破坏呢?
首先假设你的数据库名为Test,这个数据库中存在一个user表,user表存放着20000个会员信息,我知道你的博客注册系统的代码是以下:
<?php $username = $_POST['username']; $password = $_POST['password']; if(empty($username) || empty($password)) { //跳转到注册界面并提示用户名或密码未填写 exit(); } //链接数据库 //假设DB类封装了不少SQL操做,析构的时候自动关闭数据库链接,具体过程不写了 //$db是一个数据库DB类的实例,存在两个方法 //$db->isUsernameExists断定是否用户名是否存在 //$db->query 执行一条SQL语句 if(!$db->isUsernameExists($username)) { $db->query("insert into user (username,password) values ('" . $username . "','" . $password . "')"); //设置session并跳转 exit(); } else { //跳转到注册界面并提示用户名已存在 exit(); }
这段代码有问题吗,我相信不少PHP Coder都会很鄙视的说到“你不就是想说SQL注入嘛”。
的确,这个就是一个SQL注入的问题,这个问题已经很古老了,好像你们都知道,为何我还要讲呢?
这是由于我以前在学校看到过几个由学弟编写的PHP项目,他们就基本上没有考虑过这个问题,不少代码就直接这么写,固然,你若是按照网上SQL注入的方式去试,会发现你根本注入不了,貌似PHP已经自动帮你解决掉这个问题了,怎么解决的呢,实际上就是对特殊字符前加上反斜线。
首先说一下为何SQL注入失败呢?若是你的php.ini中配置了自动转义,PHP会在你将数据插入到DB以前对数据进行转义。
貌似这样咱们就不用考虑这个问题了,可是实际上PHP帮咱们作了这些才让事情更可怕,若是你将你的程序转移到另一台linux服务器, 这台服务器上面php.ini配置文件中配置了不自动进行转义,那么你的程序一会儿问题就大了,咱们不该该将咱们代码的安全性依赖于服务器的配置。那么怎么搞定这个事情呢?
幸亏,PHP中已经有了addslashes函数,它会对特殊字符进行转义,可是很遗憾,经过查看PHP手册发现:
默认状况下,PHP 指令 magic_quotes_gpc 为 on,它主要是对全部的 GET、POST 和 COOKIE 数据自动运行 addslashes()。不要对已经被 magic_quotes_gpc 转义过的字符串使用 addslashes(),由于这样会致使双层转义。遇到这种状况时可使用函数 get_magic_quotes_gpc() 进行检测
那怎么作呢,幸亏PHP已经提供了一个get_magic_quotes_gpc函数能够来断定是否已经开启了magic_quotes_gpc,因此咱们能够自定义一个addslashes函数,如:
<?php function myAddslashes($str) { if(get_magic_quotes_gpc()){ return addslashes($str); } }其实还有另外的方法解决这个问题:
1. 使用PDO来访问DB,PDO中可使用PDOStatement->bindParam,这样,PDO会自动帮你作好这一切,而且我我的以为PDO颇有前途!!
2. 若是get_magic_quotes_gpc为on,首先调用stripslashes去除转义字符,而后在插入数据库以前使用mysql_real_escape_string,我我的以为这种方式比第一种方式靠谱!!
固然,说了这么多,有可能还有童鞋不知道什么是SQL注入,我就简略的讲一下SQL注入的过程啊,熟悉SQL注入的人直接pass掉这一段。
按照上面的例子,假设用户在password这个字段输入的值为a');drop table user;...,那么执行SQL的时候SQL语句就会变成:
insert into user (username,password) values ('用户名','a');drop table user;...')
这个SQL首先会向user表插入一条记录,而后删除整个表,而后。。。。SQL出错了。
不过无论SQL是否出错,user表已经没有了,对于一个会员10000的博客,用户表没有了,我以为损失仍是蛮大的,固然,你也能够将链接数据库的用户的权限下降,没有删除表的权限,可是这样也不是一个治本的方法,仍是解决掉SQL注入漏洞比较靠谱。
好,解决掉SQL注入,我再说一下XSS(跨站脚本漏洞)的问题。
现有一段PHP的脚本:
<?php echo $_GET['a'];我才讲到这个的代码是有问题的,上面说的是有时候会抛出警告,可是若是传递参数的时候被不法分子利用,这个问题就大多了。
如今假设访问这个脚本的URL是:http://localhost/test.php?a=a,我将参数a的值设为a,传递过去一点问题都没有吧,可是如今假设我值换一下,URL变成了:
http://localhost/test.php?a=<script>location.href="http://www.tmall.com"</script>,那么执行脚本的时候就会跳转到天猫首页,这样恐怖吧!!
若是这个不是跳转到天猫,而是跳转到某一个黑客设好的网址,他就可能将你的Cookie信息弄到,而后就能够伪造Cookie,用你的身份登陆博客系统,而后。。。。你懂的。
解决这个问题的方法也很简单,就是字符串转义就OK,实际上就能够经过咱们自定义的这个myAddslashes方法来作,调用了这个方法以后,脚本没法执行了,可是有时候咱们又须要执行脚本,那怎么作呢,咱们能够对输入的字符串按照必定的规则过滤,具体怎么使用的能够参照手册。
解决掉这个问题以后,我再说另一个问题,这个问题就是CSRF(跨站点请求伪造漏洞),这是个什么东东!!!
现假设你有一个留言的系统,留言的内容是富文本的,用户能够添加表情等等,表情的HTML代码是<img src = "XXX" />,假设用户填写的表情是经过你提供的富文本编辑器来作的,没有任何问题,可是若是他不使用这个,而是利用img标签作了另一个事情呢?
怎么作呢?很简单的,就是改变img标签的src属性:
<img src = "http://www.tmall.com" />
提交留言以后发现这个图片没法显示,为何没法显示其实也很简单,根本不是一个合法的图片连接,可是当一个不知情的用户A查看留言的时候,会发生什么状况,每次用户打开这个留言的页面,实际上就会访问www.tmall.com一次,若是将这个网址改为黑客的网址,那么结果,仍是你懂的。。。
其实除了这些,还有上传文件的漏洞等等,因为时间有限,就不说了。
我讲这些实际上就是为了说明,安全问题实际上很重要,咱们在编程序的时候要考虑的东西其实是不少的。
原本今天还要讲怎么在框架中怎么去解决这些问题,可是又超出我预计的一个小时的时间了,那就下次再说了。
SQL注入和XSS实际上我已经讲了怎么防止,可是CSRF怎么防止呢?