检测文件类型并且用用户上存文件名保存
代码如下:if(isset($_FILES[
img
])){$file = save_file($_FILES[
img
]);if($file===false) exit(
上存失败!
);echo "上存成功!"
$file;}function check_file($img){///读取文件if($img[
error
]>
) return false;$tmpfile = $img[
tmp_name
];$filename = $img[
name
];///读取文件扩展名$len=strrpos($filename
"
");if($len===false) return false;//得到扩展名$ext = strtolower(substr($filename
$len+
));if(!in_array($ext
array(
jpg
jpeg
png
))) return false;return true;}function save_file($img){if(!check_file($img)) return false;//格式检测ok
准备移动数据$filename = $img[
name
];$newfile = "upload/"
$filename;if(!move_uploaded_file($img["tmp_name"]
$newfile)) return false;return $newfile;}?>以上代码
对输入类型也做了判断
看了没有问题
但是问题
确恰恰出现在对获取的用户名变量检测上面
直接获取传入用户名
然后存为文件
有朋友会说
这些文件名都是我电脑里面存在的
文件名格式都受限于操作系统对文件名定义
但是
需要注意是
对于$_FILES里面获取变量
是直接来自http request请求
它跟普通获取其它get
post变量一样
因此
别有用心的人
往往会自己模拟浏览器
给服务器发送一个特殊文件名
然后
让存文件时候
能够正常保存为自己格式
前些年
”” 在字符串中
保存为文件
会自动截断后面内容
如
$filename 构造为
”a
php
jpg”
我们想想
将会变成怎么样?$newfile = “upload/a
php
jpg” 因为
对扩展名验证
最右边”
”后面字符是jpg
是允许图片格式
但是
我们一以该文件名
保存
发现磁盘会在upload目录下面生成a
php
后面所有字符
被自动截断
该漏洞
风靡一时
当时几乎大多数上存网站都有漏洞
一时
很多平台关闭了上存
其实
根本原因就在此
我们拿到文件名
自己作为最终生成文件名保存了
好的方法
是自己随机生成文件名+读取扩展名
这样可以组织输入特殊字符
在进行文件保存时候
被抛弃或截断了
php
时代这个漏洞可以利用
到php
时代
生成的变量文件名值中
会自动过滤掉””
这样无论用户构造怎么样的特殊””用户名
都会被截断
但是
目前这类漏洞
在asp
jsp 等站点
还经常有出现
老版本的php站点也会经常出现