php中防止伪造跨站请求的小招式


Posted in PHP onSeptember 02, 2011

伪造跨站请求介绍

伪造跨站请求比较难以防范,而且危害巨大,攻击者可以通过这种方式恶作剧,发spam信息,删除数据等等。这种攻击常见的表现形式有:

伪造链接,引诱用户点击,或是让用户在不知情的情况下访问

伪造表单,引诱用户提交。表单可以是隐藏的,用图片或链接的形式伪装。

比较常见而且也很廉价的防范手段是在所有可能涉及用户写操作的表单中加入一个随机且变换频繁的字符串,然后在处理表单的时候对这个字符串进行检查。这个随机字符串如果和当前用户身份相关联的话,那么攻击者伪造请求会比较麻烦。

yahoo对付伪造跨站请求的办法是在表单里加入一个叫.crumb的随机串;而facebook也有类似的解决办法,它的表单里常常会有post_form_id和fb_dtsg。

随机串代码实现

咱们按照这个思路,山寨一个crumb的实现,代码如下:

<?php 
class Crumb { 
CONST SALT = "your-secret-salt"; 
static $ttl = 7200; 
static public function challenge($data) { 
return hash_hmac('md5', $data, self::SALT); 
} 
static public function issueCrumb($uid, $action = -1) { 
$i = ceil(time() / self::$ttl); 
return substr(self::challenge($i . $action . $uid), -12, 10); 
} 
static public function verifyCrumb($uid, $crumb, $action = -1) { 
$i = ceil(time() / self::$ttl); 
if(substr(self::challenge($i . $action . $uid), -12, 10) == $crumb || 
substr(self::challenge(($i - 1) . $action . $uid), -12, 10) == $crumb) 
return true; 
return false; 
} 
}

代码中的$uid表示用户唯一标识,而$ttl表示这个随机串的有效时间。

应用示例

构造表单

在表单中插入一个隐藏的随机串crumb

<form method="post" action="demo.php"> 
<input type="hidden" name="crumb" value="<?php echo Crumb::issueCrumb($uid)?>"> 
<input type="text" name="content"> 
<input type="submit"> 
</form>

处理表单 demo.php

对crumb进行检查

<?php 
if(Crumb::verifyCrumb($uid, $_POST['crumb'])) { 
//按照正常流程处理表单 
} else { 
//crumb校验失败,错误提示流程 
} 
?>
PHP 相关文章推荐
信用卡效验程序
Oct 09 PHP
PHP XML备份Mysql数据库
May 27 PHP
php 小乘法表实现代码
Jul 16 PHP
php 定界符格式引起的错误
May 24 PHP
MySQL的FIND_IN_SET函数使用方法分享
Mar 27 PHP
php网站判断用户是否是手机访问的方法
Nov 01 PHP
CodeIgniter常用知识点小结
May 26 PHP
laravel学习教程之存取器
Jul 30 PHP
PHP使用星号隐藏用户名,手机和邮箱的实现方法
Sep 22 PHP
thinkphp整合微信支付代码分享
Nov 24 PHP
解决thinkPHP 5 nginx 部署时,只跳转首页的问题
Oct 16 PHP
详解php反序列化
Jun 10 PHP
10个实用的PHP代码片段
Sep 02 #PHP
PHP文件操作实现代码分享
Sep 01 #PHP
深入探讨PHP中的内存管理问题
Aug 31 #PHP
php中使用Imagick实现图像直方图的实现代码
Aug 30 #PHP
PHP正确配置mysql(apache环境)
Aug 28 #PHP
PHP MySQL应用中使用XOR运算加密算法分享
Aug 28 #PHP
PHP 时间日期操作实战
Aug 26 #PHP
You might like
一个取得文件扩展名的函数
2006/10/09 PHP
php 短链接算法收集与分析
2011/12/30 PHP
PHP中使用crypt()实现用户身份验证的代码
2012/09/05 PHP
thinkPHP实现将excel导入到数据库中的方法
2016/04/22 PHP
PHP 进度条函数的简单实例
2017/09/19 PHP
php反射学习之不用new方法实例化类操作示例
2019/06/14 PHP
Yii框架的路由配置方法分析
2019/09/09 PHP
jQuery+PHP实现图片上传并提交功能
2020/07/27 PHP
JavaScript初学者应注意的七个细节详细介绍
2012/12/27 Javascript
js处理自己不能定义二维数组的方法详解
2014/03/03 Javascript
jQuery插件制作之全局函数用法实例
2015/06/01 Javascript
常用javascript表单验证汇总
2020/07/20 Javascript
Bootstrap treeview实现动态加载数据并添加快捷搜索功能
2018/01/07 Javascript
vue2.0 实现导航守卫(路由守卫)
2018/05/21 Javascript
layui输入框只允许输入中文且判断长度的例子
2019/09/18 Javascript
微信小程序 生成携带参数的二维码
2019/10/23 Javascript
JS JQuery获取data-*属性值方法解析
2020/09/01 jQuery
在Vue中获取自定义属性方法:data-id的实例
2020/09/09 Javascript
[01:07:13]TNC vs Pain 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
[50:22]完美盛典-2018年度红毯走秀
2018/12/16 DOTA
python xml.etree.ElementTree遍历xml所有节点实例详解
2016/12/04 Python
Python中easy_install 和 pip 的安装及使用
2017/06/05 Python
python 用lambda函数替换for循环的方法
2018/06/09 Python
Python3.8对可迭代解包的改进及用法详解
2019/10/15 Python
wxpython多线程防假死与线程间传递消息实例详解
2019/12/13 Python
Anaconda3中的Jupyter notebook添加目录插件的实现
2020/05/18 Python
pycharm 实现调试窗口恢复
2021/02/05 Python
HTML5 weui使用笔记
2019/11/21 HTML / CSS
世界上最大的街头服饰网站:Karmaloop
2017/02/04 全球购物
印尼购物网站:iLOTTE
2019/10/16 全球购物
什么是接口(Interface)?
2013/02/01 面试题
好听的队名和口号
2014/06/09 职场文书
航海技术专业毕业生推荐信
2014/07/09 职场文书
医生个人自我剖析材料
2014/10/08 职场文书
社区党的群众路线教育实践活动总结材料
2014/10/31 职场文书
React 并发功能体验(前端的并发模式)
2021/07/01 Javascript