首页 » SEO优化 » php逝世轮回404技巧_开拓中php安然性推敲哪些

php逝世轮回404技巧_开拓中php安然性推敲哪些

duote123 2024-12-09 0

扫一扫用手机浏览

文章目录 [+]

1、把握整站的构造,避免透露站点敏感目录

在写代码之初,我也是像很多老源码一样,在根目录下放上index.php、register.php、login.php,用户点击注书页面,就跳转到http://localhost/register.php。
并没有太多的构造的思想,像这样的代码构造,最大的问题倒不是安全性问题,而是代码扩展与移植问题。

php逝世轮回404技巧_开拓中php安然性推敲哪些

在写代码的过程中,我们常要对代码进行修正,这时候如果代码没有统一的一个入口点,我们可能要改很多地方。
后来我读了一点emlog的代码,创造网站真正的前端代码都在模板目录里,而根目录下就只有入口点文件和配置文件。
这才顿悟,对全体网站的构造进行了修正。

php逝世轮回404技巧_开拓中php安然性推敲哪些
(图片来自网络侵删)

网站根目录下放上一个入口点文件,让它来对全体网站所有页面进行管理,这个时候注书页面变成了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),才能实行后面的代码。

2、利用预编译语句,避免sql注入

注入是早前很大的一个问题,不过近些年由于大家比较重视这个问题,以是逐步变得好了很多。

吴翰清在web白帽子里说的很好,实在很多漏洞,像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方法绑天命据

//大家可以看出来,由于我留了两个?,也便是要向个中绑定两个数据,以是第一个参数是绑定的数据的类型(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 '登录失落败';}

?>

3、预防XSS代码,如果不须要利用cookie就不该用

在我的网站中并没有利用cookie,更由于我对权限限定的很去世,以是对付xss来说危险性比较小。

对付xss的防御,也是一个道理,处理好“代码”和“数据”的关系。
当然,这里的代码指的便是javascript代码或html代码。
用户能掌握的内容,我们一定要利用htmlspecialchars等函数来处理用户输入的数据,并且在javascript中要谨慎把内容输出到页面中。

4、限定用户权限,预防CSRF

现在脚本漏洞比较火的便是越权行为,很多主要操作利用GET办法实行,或利用POST办法实行而没有核实实行者是否知情。

CSRF很多同学可能比较陌生,实在举一个小例子就行了:

A、B都是某论坛用户,该论坛许可用户“赞”某篇文章,用户点“赞”实在是访问了这个页面:http://localhost/?act=support&articleid=12。
这个时候,B如果把这个URL发送给A,A在不知情的情形下打开了它,即是说给articleid=12的文章赞了一次。

以是该论坛换了种办法,通过POST办法来赞某篇文章。

<form action=\"大众http://localhost/?act=support\"大众 method=\"大众POST\公众>

<input type=\"大众hidden\公众 value=\"大众12\公众 name=\"大众articleid\公众>

<input type=\公众submit\"大众 value=\"大众赞\"大众>

</form>

可以看到一个隐蔽的input框里含有该文章的ID,这样就不能通过一个URL让A点击了。
但是B可以做一个“极具诱惑力”的页面,个中某个按钮就写成这样一个表单,来诱惑A点击。
A一点击,依旧还是赞了这篇文章。

末了,该论坛只好把表单中增加了一个验证码。
只有A输入验证码才能点赞。
这样,彻底去世了B的心。

但是,你见过哪个论坛点“赞”也要输入验证码?

以是吴翰清在白帽子里也推举了最好的办法,便是在表单中加入一个随机字符串token(由php天生,并保存在SESSION中),如果用户提交的这个随机字符串和SESSION中保存的字符串同等,才能赞。

在B不知道A的随机字符串时,就不能越权操作了。

我在网站中也多次利用了TOKEN,不管是GET办法还是POST办法,常日就能抵御99%的CSRF估计了。

5、严格掌握上传文件类型

上传漏洞是很致命的漏洞,只要存在任意文件上传漏洞,就能实行任意代码,拿到webshell。

我在上传这部分,写了一个php类,通过白名单验证,来掌握用户上传恶意文件。
在客户端,我通过javascript先验证了用户选择的文件的类型,但这只是善意地提醒用户,终极验证部分,还是在做事端。

白名单是必要的,你如果只许可上传图片,就设置成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推举利用的。

好了,我能想到的,也是在实际利用中用到的东西也就这么多了。
这也仅仅是我自己写代码中积累的一些对代码安全性的一个见地,如果大家还有更好的想法,可以和我互换。
希望大家也能写出更安全的代码。

标签:

相关文章

轮回履行php技巧_PHP 轮回While 轮回

PHP 循环在您编写代码时,您常常须要让相同的代码块一次又一次地重复运行。我们可以在代码中利用循环语句来完成这个任务。在 PHP...

SEO优化 2024-12-10 阅读0 评论0

phpwechatlogin技巧_给你代码网站微信登录接入

前段韶光公司决定登录模块接入主流第三方平台,第一个便是微信。开拓占用的韶光并不多,紧张是前期的准备事情:从注册到实名认证,再到开拓...

SEO优化 2024-12-10 阅读0 评论0