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保留两位小数并且四舍五入及不四舍五入的方法
Sep 22 PHP
Yii结合CKEditor实现图片上传功能
Jun 13 PHP
PHP伪造来源HTTP_REFERER的方法实例详解
Jul 06 PHP
php析构函数的简单使用说明
Aug 24 PHP
php中注册器模式类用法实例分析
Nov 03 PHP
php unicode编码和字符串互转的方法
Aug 12 PHP
PHP编程获取图片的主色调的方法【基于Imagick扩展】
Aug 02 PHP
yii2 commands模式以及配置crontab定时任务的方法
Aug 19 PHP
Yii2.0 RESTful API 基础配置教程详解
Dec 26 PHP
laravel框架语言包拓展实现方法分析
Nov 22 PHP
PHP设计模式之迭代器模式Iterator实例分析【对象行为型】
Apr 26 PHP
Laravel中如何轻松容易的输出完整的SQL语句
Jul 26 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第一季视频教程(李炎恢+php100 不断更新)
2011/05/29 PHP
PHP实现根据数组的值进行分组的方法
2017/04/20 PHP
laravel admin实现分类树/模型树的示例代码
2020/06/10 PHP
如何将JS的变量值传递给ASP变量
2012/12/10 Javascript
jquery获取select选中值的方法分析
2015/12/22 Javascript
jQuery使用$.each遍历json数组的简单实现方法
2016/04/18 Javascript
JavaScript代码实现图片循环滚动效果
2020/03/19 Javascript
浅谈Web页面向后台提交数据的方式和选择
2016/09/23 Javascript
微信小程序 摇一摇抽奖简单实例实现代码
2017/01/09 Javascript
JavaScript实现经纬度转换成地址功能
2017/03/28 Javascript
详解利用jsx写vue组件的方法示例
2017/07/17 Javascript
js+css实现红包雨效果
2018/07/12 Javascript
iview同时验证多个表单问题总结
2018/09/29 Javascript
在Vue中获取自定义属性方法:data-id的实例
2020/09/09 Javascript
antd日期选择器禁止选择当天之前的时间操作
2020/10/29 Javascript
python获得一个月有多少天的方法
2015/06/04 Python
python3制作捧腹网段子页爬虫
2017/02/12 Python
python中requests爬去网页内容出现乱码问题解决方法介绍
2017/10/25 Python
Django开发中复选框用法示例
2018/03/20 Python
Python GUI学习之登录系统界面篇
2019/08/21 Python
python 模拟贷款卡号生成规则过程解析
2019/08/30 Python
浅谈Keras参数 input_shape、input_dim和input_length用法
2020/06/29 Python
HTML5+CSS3实例 :canvas 模拟实现电子彩票刮刮乐代码
2016/12/30 HTML / CSS
详解canvas绘制多张图的排列顺序问题
2019/01/21 HTML / CSS
1688平价精选商城:阿里集团旗下,工厂出厂价格直销
2017/04/24 全球购物
ZINVO手表官网:男士和女士手表
2019/03/10 全球购物
奥地利体育网上商店:Gigasport
2019/10/09 全球购物
进程的查看和调度分别使用什么命令
2015/03/25 面试题
银行会计职员个人的自我评价
2013/09/29 职场文书
班长自荐书范文
2014/02/11 职场文书
2015元旦家电促销活动策划方案
2014/12/09 职场文书
关于开学的感想
2015/08/10 职场文书
校园安全主题班会
2015/08/12 职场文书
详解mysql三值逻辑与NULL
2021/05/19 MySQL
OpenCV-Python直方图均衡化实现图像去雾
2021/06/07 Python
Python OpenCV形态学运算示例详解
2022/04/07 Python