how to write a php framework,怎么一步步编写简单的PHP的Framework(十四)
今天我说一下怎么在框架中over掉这些安全问题。
首先是SQL注入,这个如果你使用的是PDO,我觉得应该没什么问题,如果你使用的还是mysql_*等API,那么你可以在框架中实现bindParameter或者在插入数据库之前进行字符串转义。
前两天把上一篇文章写完之后,Vian在后面留言说到过SQL注入的一个解决方案,就是在在插入DB之前进行'''.addslashes($id).''',它的意思就是首先进行addslashes操作,之后再强制单引号包裹,这样它就是一个不折不扣的字符串了,所以就注入不了,我觉得这个方法不错,赞一个!!
由于SQL注入需要联系到模型,XSS需要联系到视图,这两块儿我都没有开始讲,所以我再后面再讲怎么在框架中解决,当然,如果我写到后面忘记了,你也可以提醒我一下。
上一次我讲CSRF的时候,并没有给出一个解决方案,今天我就给出这个解决方案。实际上解决的方法很简单,就是给它产生一个随机数,然后后端判定传递过来的数和正确的数是否吻合, 如果不吻合,就不执行相应的代码了,这个随机数我们称为token。
为了简单,我们就将产生token和得到token的函数都写在控制器中,即Controller.php。
首先是生成随机数,最简单的方式是使用mt_rand()直接产生一个整数,但在这儿我使用之前我在initphp这个框架中看到的解决csrf的方法,在这儿,也谢谢initphp作者的思路:
initphp的代码是:
private function set_token() {
if (!$_COOKIE['init_token']) {
$str = substr(md5(time(). $this->get_useragent()), 5, 8);
setcookie("init_token", $str, NULL, '/');
$_COOKIE['init_token'] = $str;
}
} 为了简单,我这儿就不使用userAgent了,initphp是将当前时间戳和userAgent拼接成字符串之后再md5加密,取出第5到8位,我这边的思路是将当前时间戳进行md5加密,然后从第0位开始取,取得的字符串长度是随机产生的:
$token = substr(md5(time()),0,mt_rand(10,15)); 为了防止随机数太大或太小,我设置mt_rand的取值范围为10到15,也就是说产生的token的位数为10到15位。
生成token之后其他的事情就好办了,当然,首先,也是设置token,我们没有必要每次用户请求的时候都产生一个随机数,所以我们将它存放在COOKIE中,框架载入的时候会判定是否有token,如果没有则动态生成一个,当然,生成的token会在一段时间之后过期失效,我这儿设置的时间为7天。
private function _setToken() {
if(empty($_COOKIE['_csrfToken'])) {
$token = substr(md5(time()),0,mt_rand(10,15));
$this->_token = $token;
setcookie('_csrfToken',$token,time() + 3600 * 24 * 7);
} else {
$this->_token = $_COOKIE['_csrfToken'];
}
}
由于生成token的过程是框架自动完成的,所以没有必要让用户看到此过程,所以将这个函数设为私有,然后在Controller类的构造函数中调用即可。
刚才是生成token,那么怎么得到token呢,实际上得到token的方法就非常简单了,就是一个简单的getter:
protected function _getToken() {
return $this->_token;
} 现在我再演示一下在用户编写的控制器的判定过程:
假设用户请求的URL是:http://localhost/index.php?c=Index&a=test&token=rwerdfdsfsdfs
那么这个控制器的类的代码如下:
class IndexController extends Controller {
public function test() {
$token = empty($_GET['token']) ? '' : $_GET['token'];
if($token === $this->_getToken()) {
//判定为正常
} else {
$this->_redirect(array(
//跳转到某一个控制器的某一个Action
));
}
}
} 可能有人会问URl上面的token值是怎么设置然后传递过来的呢?
我们可以想一下,假设上一个页面是Index控制器的test2这个Action,那么我们可以在test2这个Action中首先使用$this->_getToken得到token值,然后在将数据传递到视图,视图中使用了之后,用户点击这个链接就可以将这个token值传递过来了。
我现在提一个问题,假设用户访问A页面的时候得到token,这个token还有两秒就过期了,这个用户三秒之后点击这个含有token的链接到达B页面,B页面由于COOKIE中的token已经失效,所以重新产生一个token,然后再和传递的这个token比较,自然不匹配,然后就跳转了,这还不是有问题的呢,那么怎么解决呢?
由于还有一点时间,所以我提一下上传文件漏洞吧,用户上传一个比如test.php页面,如果用户没有做文件类型的判定,用户上传这个php文件之后,按照链接访问这个页面,有可能这个页面中有一些破坏性的代码,整个网站就危险了。
可能你已经在程序中判定了,只允许后缀为jpg,png,gif这三种类型,那么我可以将这个jsp页面后缀改成如jpg,上传成功之后,如果网站存在某种漏洞能够让它修改文件后缀,那么你的网站又危险了!!
还假设你的网站不允许修改文件后缀名,但是它在上传的图片后面加上一段JS脚本或者在上传的文件名上面写一些脚本,这些都可能很危险!!
所以,做好一个WEB应用不是想象中那么容易的,刚才说的是安全这一块儿的内容,实际上当访问量大了之后,之前你觉得完全不是问题的问题可能就变成了一个大的问题,除了这两个,还有其他N个问题,所以,保持低调,继续学习,继续提高。。。。
上面一段话仅以自勉,其他人可以忽略。
大四了,还有一个月就要离开天猫回学校做毕设了,我很想在毕业之前给我的网站做一个大幅度的修改,但是我现在不知道到底要做什么,不过肯定这个网站是针对程序员的,希望大家提一点意见,我的个人网站http://www.qingyueit.com(比较挫,好久都没有更新文章了,甚至连界面也是直接用了别人的主题)。
本次代码点此下载
how to write a php framework,怎么一步步编写简单的PHP的Framework(十四)相关推荐
- 怎么一步步编写简单的PHP的Framework(二十一)
2019独角兽企业重金招聘Python工程师标准>>> 前几天我讲到在SqlParser中完成SQL的解析,我已经讲了distinct,field,table,group,order ...
- 怎么一步步编写简单的PHP的Framework(五)
2019独角兽企业重金招聘Python工程师标准>>> 上一次我讲到使用自动导入可以实现一个类的延迟加载,这一次我想讲一下配置文件. 不知道大家注意了没有,前几篇文章我都没有涉及到配 ...
- 怎么一步步编写简单的PHP的Framework(十九)
2019独角兽企业重金招聘Python工程师标准>>> 上一次我说了一下怎么从ModelBase通过Sql parse将SQL拆分,也就是解析的过程,今天我详细的说一下. 首先,我们 ...
- Robot Framework(十七) 扩展RobotFramework框架——扩展Robot Framework Jar
4.4扩展Robot Framework Jar 使用标准JDK安装中包含的jar命令,可以非常简单地向Robot Framework jar添加其他测试库或支持代码.Python代码必须放在jar里 ...
- 第六十四期:微软将不再把 .NET Framework API 移植到 .NET Core 3.0
投递人 itwriter 目前 .NET Core 3.0 拥有的 API 总数约为 .NET Framework API 的 80%,剩下尚未从 .NET Framework 移植到 .NET Co ...
- ASP.NET企业开发框架IsLine FrameWork系列之十四--框架配置信息大全(中)
ASP.NET企业开发框架IsLine FrameWork系列之十四--框架配置信息大全(中) 接上文 上文中讲到配置日志模块的第二步,这篇文章继续给大家介绍日志配置方法. Step 3.在</ ...
- 脱离.Net Framework运行doNet程序的简单方法
脱离.Net Framework运行doNet程序的简单方法(Console) 在.Net Framework下,你就算写一个小小的控制台程序,哪怕只有几K大小,我们必须要安装一个几十M的Framew ...
- [19]Window管理框架WMF(Window Management Framework) 5.0 VS Window管理框架WMF(Window Management Framework) 5.1
最近笔者在研究PowerShell DSC, 我们知道PowerShell DSC是PowerShell的一部分,而PowerShell又是WMF(Window Management Framewor ...
- Entity Framework 6 Code First的简单使用和更新数据库结构
一.安装Entity Framework 6 在项目中右击选择"管理NuGet程序包",联机搜索Entity Framework,点击安装 二.配置数据库连接 在App.confi ...
最新文章
- python3并发编程基础
- GitHub高赞:给文字打马赛克=形同虚设,AI看透你一切小心思,已开源
- android触摸外部关闭键盘,如何隐藏Android上的软键盘,点击外部EditText?
- nginx配置文件语法高亮的Sublime Text扩展
- Android Ac 控件,Android控件--MultiAutoCompleteTextView
- mapreduce程序调用各个类的功能
- 怎么判断网络回路_地暖管漏水怎么办?一打、二看、三确定,及时查出地暖管漏水点!...
- 《众妙之门 JavaScript与jQuery技术精粹》 - 读书笔记总结[无章节版][1-60]
- uboot 之环境变量
- 通信系统设计中的凸优化问题
- TCP/IP---ping命令
- 计算机基础(06)计算机网络应用
- 神经网络计算棒怎么用,英特尔神经计算棒拆解
- html5模拟真实摇骰子,Axure教程:模拟真实摇骰子交互
- 计算机体系结构 ---- flynn 分类
- 【100%通过率】华为OD机试真题 Java 实现【完美走位】【2022.11 Q4新题】
- 神奇英语语法系列(1)——定语从句
- speedoffice(Word)如何添加批注
- PEAR modules 环境检测安装软件始终 NOK
- android团购客户端,领团网团购导航Android手机客户端获机锋网力推
热门文章
- python与正则表达式(part4)--正则表达式分组
- 机器学习第三篇:详解朴素贝叶斯算法
- 介绍一个使用 cl_abap_corresponding 进行两个内表不同名称字段赋值的快捷方法
- SAP Fiori 应用里图标(Icon)的渲染原理和使用技巧
- SAP Spartacus B2B Unit page convertListItem方法的工作原理
- SAP Spartacus FeaturesConfig
- Angular应用动态创建style标签页的场景
- 从HTTP 400 bad request说起 - 一个函数被注释掉后引起的血案
- 如何将SAP UI5应用配置到SAP云平台Fiori Launchpad里
- upload Fiori application to ABAP server via report /UI5/UI5_REPOSITORY_LOAD