开发中php安全性考虑哪些( 三 )


白名单是必要的 , 你如果只允许上传图片 , 就设置成array('jpg','gif','png','bmp') , 当用户上传来文件后 , 取它的文件名的后缀 , 用in_array验证是否在白名单中 。
在上传文件数组中 , 会有一个MIME类型 , 告诉服务端上传的文件类型是什么 , 但是它是不可靠的 , 是可以被修改的 。在很多存在上传漏洞的网站中 , 都是只验证了MIME类型 , 而没有取文件名的后缀验证 , 导致上传任意文件 。
所以我们在类中完全可以忽略这个MIME类型 , 而只取文件名的后缀 , 如果在白名单中 , 才允许上传 。
当然 , 服务器的解析漏洞也是很多上传漏洞的突破点 , 所以我们尽量把上传的文件重命名 , 以“日期时间+随机数+白名单中后缀”的方式对上传的文件进行重命名 , 避免因为解析漏洞而造成任意代码执行 。
6、加密混淆javascript代码 , 提高攻击门槛
很多xss漏洞 , 都是黑客通过阅读javascript代码发现的 , 如果我们能把所有javascript代码混淆以及加密 , 让代码就算解密后也是混乱的(比如把所有变量名替换成其MD5 hash值) , 提高阅读的难度 。
7、使用更高级的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我们的密码了
8、验证码安全性
验证码通常是由php脚本生成的随机字符串 , 通过GD库的处理 , 制作成图片 。真正的验证码字符串保存在SESSION中 , 然后把生成的图片展示给用户 。用户填写了验证码提交后 , 在服务端上SESSION中的验证码进行比对 。
由此想到了我之前犯过的一个错误 。验证码比对完成之后 , 不管是正确还是错误 , 我都没有清理SESSION 。这样产生了一个问题 , 一旦一个用户第一次提交验证码成功 , 第二次以后不再访问生成验证码的脚本 , 这时候SESSION中的验证码并没有更新 , 也没有删除 , 导致验证码重复使用 , 起不到验证的作用 。
再就说到了验证码被识别的问题 , WordPress包括emlog的程序我经常会借鉴 , 但他们所使用的验证码我却不敢恭维 。很多垃圾评论都是验证码被机器识别后产生的 , 所以我后来也使用了一个复杂一点的验证码 , 据说是w3c推荐使用的 。
好了 , 我能想到的 , 也是在实际运用中用到的东西也就这么多了 。这也仅仅是我自己写代码中积累的一些对代码安全性的一个见解 , 如果大家还有更好的想法 , 可以和我交流 。希望大家也能写出更安全的代码 。


推荐阅读