更加多学习视频分享
想要领取整套学习视频教程(包含更加多的IT学习视频)的朋友,能够加QQ 2084533608,加入时验证信息填:学习
“容易学PHP”,有学习文档,框架视频教程,网站教程,供给百度分享给大众下载,保藏。大众关注后回复关键词,便可获取!平台将与大众分享前端到后端的实例,学习语法,学习教程,技巧等!欢迎大众关注!
正文如下:
把握整站的结构,避免泄密站点敏锐目录
在写代码之初,我亦是像非常多老源码同样,在根目录下放上index.php、register.php、login.php,用户点击注册页面,就转到http://localhost/register.php。并无太多的结构的思想,像这般的代码结构,最大的问题倒不是安全性问题,而是代码扩展与移植问题。
在写代码的过程中,咱们常要对代码进行修改,此时候倘若代码无统一的一个入口点,咱们可能要改非常多地区。后来我读了一点emlog的代码,发掘网站真正的前端代码都在模板目录里,而根目录下就仅有入口点文件和配置文件。这才顿悟,对全部网站的结构进行了修改。
网站根目录下放上一个入口点文件,让它来对全部网站所有页面进行管理,这个时候注册页面变成为了http://localhost/?act=register,任何页面只是act的一个参数,在得到这个参数后,再用一个switch来选取要包括的文件内容。在这个入口点文件中,还能够包括有些常量的定义,比如网站的绝对路径、网站的位置、数据库用户秘码。以后咱们在脚本的编写中,尽可能运用绝对路径而不要运用相对路径(否则脚本倘若改变位置,代码亦要变),而这个绝对路径就来自入口点文件中的定义。
当然,在安全性上,一个入口点文件亦能隐匿后台位置。像这般的位置http://localhost/?act=xxx不会暴露后台绝对路径,乃至能够经常更改,不消改变太多代码。一个入口点文件亦能够验证拜访者的身份,例如一个网站后台,不是管理员就不准许查看任何页面。在入口点文件中就能够验证身份,倘若无登录,就输出404页面。
有了入口点文件,我就把所有非入口点文件前面加上了这句话: <?
php
if(!defined(WWW_ROOT)){header("HTTP/1.1 404 Not Found");exit
;}
?>
WWW_ROOT是我在入口点中定义的一个常量,倘若用户是经过这个页面的绝对路径拜访(http://localhost/register.php),我就输出404错误;仅有经过入口点拜访(http://localhost/?act=register),才可执行后面的代码。
运用预编译语句,避免sql注入
注入是早前很大的一个问题,不外近些年由于大众比较注重这个问题,因此慢慢变得好了非常多。
其实非常多漏洞,像sql注入或xss,都是将“数据”和“代码”无区掰开。“代码”是程序员写的内容,“数据”是用户能够改变的内容。倘若咱们写一个sql语句select * from admin where username=admin password=xxxxx, admin和xxxxx便是数据,是用户输入的用户名和秘码,但倘若无任何处理,用户输入的就可能是“代码”,例如or =,这般就造成为了漏洞。“代码”是绝对不能让用户接触的。
在php中,针对mysql数据库有两个模块,mysql和mysqli,mysqli的意思便是mysql improve。mysql的改进版,这个模块中就含有“预编译”这个概念。像上面那个sql语句,改一改:select * from admin where username=? password=?,它就不是一个sql语句了,然则能够经过mysqli的预编译功能先把他编译成stmt对象,在后期用户输入账号秘码后,用stmt->bind_param将用户输入的“数据”绑定到这两个问号的位置。这般,用户输入的内容就只能是“数据”,而不可能变成“代码”。
这两个问号限定了“数据”的位置,以及sql语句的结构。咱们能够把咱们所有的数据库操作都封装到一个类中,所有sql语句的执行都进行预编译。这般就完全避免了sql注入,这亦是吴翰清最举荐的处理方法。
下面是运用mysqli的有些代码部分(所有的判断函数运行成功或失败的代码我都省略了,但不表率不重要): <?
php
//用户输入的数据
$name=admin
;
$pass =123456
;
//首要新建mysqli对象,构造函数参数中包括了数据库关联内容。
$conn =new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT
);
//设置sql语句默认编码
$this->mysqli->set_charset("utf8"
);
//创建一个运用通配符的sql语句
$sql =SELECT user_id FROM admin WHERE username=? AND password=?;
;
//编译该语句,得到一个stmt对象.
$stmt = $conn->prepare($sql
);
/********************
之后的内容就能重复利用,不消再次编译
*************************/
//用bind_param办法绑定数据
//大众能够看出来,由于我留了两个?,亦便是要向其中绑定两个数据,因此第1个参数是绑定的数据的类型(s=string,i=integer),第二个以后的参数是要绑定的数据
$stmt->bind_param(ss, $name, $pass
);
//调用bind_param办法绑定结果(倘若只是检测该用户与秘码是不是存在,或只是一个DML语句的时候,不消绑定结果)
//这个结果便是我select到的字段,有几个就要绑定几个
$stmt->bind_result($user_id
);
//执行该语句
$stmt->execute
();
//得到结果
if($stmt->fetch()){ echo 登陆成功;//必定要重视释放结果资源,否则后面会出错 $stmt->free_result();return $user_id;
//返回刚才select到的内容
}else
{
echo 登录失败
;
}
?>
预防XSS代码,倘若不需要运用cookie就不运用
在我的网站中并无运用cookie,更由于我对权限限制的很死,因此针对xss来讲危险性比较小。
针对xss的防御,亦是一个道理,处理好“代码”和“数据”的关系。当然,这儿的代码指的便是javascript代码或html代码。用户能掌控的内容,咱们必定要运用htmlspecialchars等函数来处理用户输入的数据,并且在javascript中要小心把内容输出到页面中。
限制用户权限,预防CSRF
此刻脚本漏洞比较火的便是越权行径,非常多重要操作运用GET方式执行,或运用POST方式执行而无核实执行者是不是知情。
CSRF非常多朋友可能比较陌生,其实举一个小例子就行了:
A、B都是某论坛用户,该论坛准许用户“赞”某篇文案,用户点“赞”其实是拜访了这个页面:http://localhost/?act=support&articleid=12。这个时候,B倘若把这个URL发送给A,A在不知情的状况下打开了它,等于说给articleid=12的文案赞了一次。
因此该论坛换了种方式,经过POST方式来赞某篇文案。 <formaction="http://localhost/?act=support"method="POST"><inputtype="hidden"value="12"name="articleid"><inputtype="submit"value="赞"
>
</form>
能够看到一个隐匿的input框里含有该文案的ID,这般就不可经过一个URL让A点击了。然则B能够做一个“极具引诱力”的页面,其中某个按钮就写成这般一个表单,来引诱A点击。A一点击,依旧还是赞了这篇文案。
最后,该论坛只好把表单中增多了一个验证码。仅有A输入验证码才可点赞。这般,彻底死了B的心。
然则,你见过哪个论坛点“赞”亦要输入验证码?
因此在这儿举荐了最好的方式,便是在表单中加入一个随机字符串token(由php生成,并保留在SESSION中),倘若用户提交的这个随机字符串和SESSION中保留的字符串一致,才可赞。
在B不晓得A的随机字符串时,就不可越权操作了。
我在网站中亦多次运用了TOKEN,不管是GET方式还是POST方式,一般就能抵御99%的CSRF估计了。
严格掌控上传文件类型
上传漏洞是很致命的漏洞,只要存在任意文件上传漏洞,就能执行任意代码,拿到webshell。
我在上传这部分,写了一个php类,经过白名单验证,来掌控用户上传恶意文件。在客户端,我经过javascript先验证了用户选取的文件的类型,但这只是善意地提醒用户,最后验证部分,还是在服务端。
白名单是必要的,你倘若只准许上传照片,就设置成array(jpg,gif,png,bmp),当用户上传来文件后,取它的文件名的后缀,用in_array验证是不是在白名单中。
在上传文件数组中,会有一个MIME类型,告诉服务端上传的文件类型是什么,然则它是不靠谱的,是能够被修改的。在非常多存在上传漏洞的网站中,都是只验证了MIME类型,而无取文件名的后缀验证,引起上传任意文件。
因此咱们在类中完全能够忽略这个MIME类型,而只取文件名的后缀,倘若在白名单中,才准许上传。
当然,服务器的解析漏洞亦是非常多上传漏洞的突破点,因此咱们尽可能把上传的文件重命名,以“日期时间+随机数+白名单中后缀”的方式对上传的文件进行重命名,避免由于解析漏洞而导致任意代码执行。
加密混淆javascript代码,加强攻击门槛
非常多xss漏洞,都是黑客经过阅读javascript代码发掘的,倘若咱们能把所有javascript代码混淆以及加密,让代码就算解密后亦是混乱的(例如把所有变量名替换成其MD5 hash值),加强阅读的难度。
运用更高级的hash算法保留数据库中重要信息
在这个硬盘容量大增的时期,非常多人持有很大的彩虹表,再加上类似于cmd5这般的网站的大行其道,单纯的md5已然等同于无物,因此咱们迫切的需要更高级的hash算法,来保留咱们数据库中的秘码。
因此后来显现了加salt的md5,例如discuz的秘码便是加了salt。其实salt便是一个秘码的“附加值”,例如A的秘码是123456,而咱们设置的salt是abc,这般保留到数据库的可能便是md5(123456abc),增多了破解的难度。
然则黑客只要得知了该用户的salt亦能跑md5跑出来。由于此刻的计算机的计算速度已然非常快了,一秒能够计算10亿次md5值,弱一点的秘码分把钟就能跑出来。
因此后来秘码学上改进了hash,引进了一个概念:密钥延伸。说简单点便是增多计算hash的难度(例如把秘码用md5()函数循环计算1000次),故意减慢计算hash所用的时间,以前一秒能够计算10亿次,改进后1秒只能计算100万次,速度慢了1000倍,这般,所需的时间亦就增多了1000倍。
那样针对咱们,怎么运用一个安全的hash计算办法?大众能够翻阅emlog的源码,能够在include目录里面找到一个HashPaaword.php的文件,其实这便是个类,emlog用它来计算秘码的hash。
这个类有一个特点,每次计算出的hash值都不同样,因此黑客不可经过彩虹表等方式破解秘码,只能用这个类中一个checkpassword办法来返回用户输入秘码的正确性。而该函数又特意增多了计算hash的时间,因此黑客很难破解她们拿到的hash值。
在最新的php5.5中,这种hash算法作为了一个正式的函数,以后就能运用该函数来hash咱们的秘码了。
验证码安全性
验证码一般是由于php脚本生成的随机字符串,经过GD库的处理,制作成照片。真正的验证码字符串保留在SESSION中,而后把生成的照片展示给用户。用户填写了验证码提交后,在服务端上SESSION中的验证码进行比对。
由此想到了我之前犯过的一个错误。验证码比对完成之后,不管是正确还是错误,我都无清理SESSION。这般产生了一个问题,一旦一个用户第1次提交验证码成功,第二次以后再也不拜访生成验证码的脚本,此时候SESSION中的验证码并无更新,亦无删除,引起验证码重复运用,起不到验证的功效。
再就说到了验证码被识别的问题,wordpress包含emlog的程序我经常会借鉴,但她们所运用的验证码我却不敢恭维。非常多垃圾评论都是验证码被设备识别后产生的,因此我后来亦运用了一个繁杂一点的验证码,据述是w3c举荐运用的。
在实质运用中用到的东西亦就这么多了。这亦仅仅是在写代码中累积的有些对代码安全性的一个见解,如果大众还有更好的想法,能够和我交流。期盼大众亦能写出更安全的代码。
点击上面微X号关注我关注我哟
博主 隔天推送php教程,php技巧,php视频教程,MySQL,笔试题等许多优秀内容,最接地气、重服务的本地微X平台!关注咱们妥妥没错!
(宣传合作联系QQ:2230304070) 宣传亦是一种生活平台需要你
阅读完文案后,望大众花个5秒的时间顺手点击一下底部的宣传,无需仔细阅读,无需关注,只要点击一下就好。平台需要你,博主感谢你!!
|