PHP中uploaded_files函数使用方法详解


Posted in PHP onMarch 09, 2011

对PHP语言有些了解的朋友们都知道,它包含有功能强大的函数库。我们今天就一起来了解一下PHP uploaded_files函数的具体功能。
在早期的PHP版本中,上传文件很可能是通过如下的代码实现的:

…… 
if (isset($_FILES['file'])) { 
$tmp_name = $_FILES['file']['tmp_name']; 
} 
if (file_exists($tmp_name)) { 
copy($tmp_name,$destfile); 
} 
……

但是很可能会被伪造一个$_FILES['file']数组出来,如果tmp_name的内容会被指定为/etc/passwd等敏感信息的内容,那么很容 易出现安全问题。PHP在后来的版本中用is_uploaded_file() 和 move_uploaded_file()解决了这个问题,用PHP uploaded_files函数不仅会检查$_FILES['file'] ['tmp_name']是否存在,而且会检查$_FILES['file']['tmp_name']是否是上传的文件,这样就使得伪造$_FILES 变量变得不可能,因为脚本会在检查到$_FILES['file']['tmp_name']不是PHP上传的时候终止执行。
伪造变得不可能了么?在很多的脚本里面我看到初试化部分就有@extract($_POST)之类的操作,以保证程序在register globals为off的环境下能继续运行,这样的环境下我们很轻松可以伪造$_FILES数组,甚至将原来的$_FILES数组覆盖,但是想完全的伪造 一个$_FILES数组还是很困难的,因为你无法饶过is_uploaded_file() 和 move_uploaded_file()。
但是在windows下的PHP环境下测试时,我们发现PHP的临时文件很有规律,是C:\WINDOWS \TEMP\PHP93.tmp这种格式,上传的时候文件名字会是C:\WINDOWS\TEMP\PHPXXXXXX.tmp这种格式变化,其中 XXXXXX是十六进制的数字,并且是按照顺序增加的,也就是说如果这次上传的临时文件名是C:\WINDOWS\TEMP\PHP93.tmp,那么下 次就会是C:\WINDOWS\TEMP\PHP94.tmp,临时文件名变得有规律。
但是我们可能不知道当前的文件名是什么,这可以通过PHP自身的错 误机制泄露出来,譬如我们将临时文件拷贝到一个没有权限的目录或者在目标文件里包含文件系统禁止的字符就可以将当前的临时文件名字给泄露出来,当然前提是 没有错误抑制处理。
那么到底如何饶过is_uploaded_file() 和 move_uploaded_file()呢?看看PHP uploaded_files函数部分的代码:
PHP_FUNCTION(is_uploaded_file) 
{ 
zval **path; 
if (!SG(rfc1867_uploaded_files)) { 
RETURN_FALSE; 
} 
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &path) != SUCCESS) { 
ZEND_WRONG_PARAM_COUNT(); 
} 
convert_to_string_ex(path); 
if (zend_hash_exists(SG(rfc1867_uploaded_files), Z_STRVAL_PP(path), Z_STRLEN_PP(path)+1)) { 
RETURN_TRUE; 
} else { 
RETURN_FALSE; 
} 
}

它 是从当前的rfc1867_uploaded_files哈希表中查找看是否当前的文件名是否存在。其中rfc1867_uploaded_files保 存了当前PHP脚本运行过程中由系统和PHP产生的有关文件上传的变量和内容。如果存在,就说明指定的文件名的确是本次上传的,否则为否。
PHP 有个很奇怪的特性就是,当你提交一个上传表单时,PHP在做处理之前这个文件就已经被上传到临时目录下面,一直到PHP脚本运行结束的时候才会销毁掉。也 就是说,你即使向一个不接受$_FILSE变量的PHP脚本提交这样一个表单,$_FILSE变量依然会产生,文件依然会被先上传到临时目录。问题就产生 了。下面的脚本可能能说明这个问题:
< ? 
$a=$_FILES['attach']['tmp_name']; 
echo $a.”………….”; 
$file='C:\\WINDOWS\\TEMP\\PHP95.tmp'; 
echo $file; 
if(is_uploaded_file($file)) echo ‘………………Yes'; 
?>

其 中C:\\WINDOWS\\TEMP\\PHP95.tmp是我猜测的临时文件名字,当时,测试这个脚本的时候我们需要向它上传一个文件或者是100个 文件,使得其中一个临时文件名为C:\\WINDOWS\\TEMP\\PHP95.tmp。如果此刻脚本有extract操作,我们就可以很方便的伪造 出一个$_FILES变量了。
不是么?可能要问伪造$_FILES变量有什么作用,我们就可以产生原来程序不允许的文件名了,PHP在处理上传的时候会对 原来的文件名有一个类似于basename()的操作,但是一旦可以伪造之后我们就可以轻易的在文件名之内加\啊../啊等等你所喜欢的任何东西
PHP uploaded_files函数的实际利用可能有点苛刻,但是也总算是PHP一点瑕疵吧,呵呵。
PHP 相关文章推荐
php intval的测试代码发现问题
Jul 27 PHP
PHP详解ASCII码对照表与字符转换
Dec 05 PHP
php中字符串和正则表达式详解
Oct 23 PHP
php防止sql注入简单分析
Mar 18 PHP
PHP超牛逼无限极分类生成树方法
May 11 PHP
PHP控制前台弹出对话框的实现方法
Aug 21 PHP
PHP编程获取各个时间段具体时间的方法
May 26 PHP
PHP用PDO如何封装简单易用的DB类详解
Jul 30 PHP
PHP实现的策略模式简单示例
Aug 25 PHP
php生成条形码的图片的实例详解
Sep 13 PHP
PHP实现动态创建XML文档的方法
Mar 30 PHP
PHP $_FILES函数详解
Mar 09 #PHP
PHP中for与foreach的区别分析
Mar 09 #PHP
php模板中出现空行解决方法
Mar 08 #PHP
在MongoDB中模拟Auto Increment的php代码
Mar 06 #PHP
PHP数组交集的优化代码分析
Mar 06 #PHP
php下安装配置fckeditor编辑器的方法
Mar 02 #PHP
PHP如何抛出异常处理错误
Mar 02 #PHP
You might like
百度工程师讲PHP函数的实现原理及性能分析(一)
2015/05/13 PHP
ThinkPHP静态缓存简单配置和使用方法详解
2016/03/23 PHP
windows7配置Nginx+php+mysql的详细教程
2016/09/04 PHP
PHP从数组中删除元素的四种方法实例
2017/05/12 PHP
从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解
2019/04/03 PHP
dojo学习第一天 Tab选项卡 实现
2011/08/28 Javascript
基于jquery跨浏览器显示的file上传控件
2011/10/24 Javascript
JavaScript高级程序设计 读书笔记之九 本地对象Array
2012/02/27 Javascript
javascript算法题 求任意一个1-9位不重复的N位数在该组合中的大小排列序号
2012/07/21 Javascript
使用insertAfter()方法在现有元素后添加一个新元素
2014/05/28 Javascript
js、jquery图片动画、动态切换示例代码
2014/06/03 Javascript
JavaScript数组去重的两种方法推荐
2016/04/05 Javascript
JavaScript 函数的执行过程
2016/05/09 Javascript
javascript实现任务栏消息提示的简单实例
2016/05/31 Javascript
javascript验证内容为数字以及长度为10的简单实例
2016/08/20 Javascript
解决axios post 后端无法接收数据的问题
2019/10/29 Javascript
用实例解释Python中的继承和多态的概念
2015/04/27 Python
Python封装shell命令实例分析
2015/05/05 Python
Python3爬取英雄联盟英雄皮肤大图实例代码
2018/11/14 Python
python矩阵/字典实现最短路径算法
2019/01/17 Python
Django保护敏感信息的方法示例
2019/05/09 Python
18个Python脚本可加速你的编码速度(提示和技巧)
2019/10/17 Python
Pytorch 实现冻结指定卷积层的参数
2020/01/06 Python
python和js交互调用的方法
2020/06/23 Python
CSS3中的常用选择器使用示例整理
2016/06/13 HTML / CSS
CSS3新增布局之: flex详解
2020/06/18 HTML / CSS
美国学校校服,儿童和婴儿服装:Cookie’s Kids
2016/10/14 全球购物
Stührling手表官方网站:男女高品质时尚手表的领先零售商
2021/01/07 全球购物
大学生实习期自我评价范文
2013/10/03 职场文书
大学毕业的自我鉴定
2013/10/08 职场文书
学术会议邀请函范文
2014/01/22 职场文书
弘扬焦裕禄精神走群众路线思想汇报
2014/09/12 职场文书
幼儿园小班见习报告
2014/10/31 职场文书
学校食堂食品安全承诺书
2015/04/29 职场文书
一文搞懂python异常处理、模块与包
2021/06/26 Python
Vue OpenLayer测距功能的实现
2022/04/20 Vue.js