用户
 找回密码
 入住 CI 中国社区

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
查看: 134|回复: 36
收起左侧

[上传/下载] 上传类 判断文件允许类型 有bug?

[复制链接]
发表于 2017-7-13 15:23:06 | 显示全部楼层 |阅读模式
QQ图片20170713151940.jpg

操作:例如 把jpg的图片改成png后缀,上传的会就会报文件类型不允许
问题: Upload类读取文件类型$this->file_type读的是文件二进制,取出来是文件的真实类型,而截图中判断的却是拿文件扩展名去对比,这不是明显不对吗
 楼主| 发表于 2017-7-13 20:05:55 | 显示全部楼层
Hex 发表于 2017-7-13 18:04
你可以把你改过的代码发上来,一起研究一下。
PHP复制代码
 
public function is_allowed_filetype($ignore_mime = FALSE)
{
    if ($this->allowed_types === '*')
    {
            return TRUE;
    }
 
    if (empty($this->allowed_types) OR ! is_array($this->allowed_types))
    {
            $this->set_error('upload_no_file_types');
            return FALSE;
    }
 
    $ext = strtolower(ltrim($this->file_ext, '.'));
 
    if ( ! in_array($ext, $this->allowed_types, TRUE))
    {
            return FALSE;
    }
 
    // Images get some additional checks
    if (in_array($ext, array('gif', 'jpg', 'jpeg', 'jpe', 'png'), TRUE) && @getimagesize($this->file_temp) === FALSE)
    {
            return FALSE;
    }
 
    if ($ignore_mime === TRUE)
    {
            return TRUE;
    }
 
    foreach($this->allowed_types as $type)
    {
        if (isset($this->_mimes[$type]))
        {
            $mime = is_array($this->_mimes[$type]) ? $this->_mimes[$type] : array($this->_mimes[$type]);
            if (in_array($this->file_type, $mime))
            {
                return true;
            }
        }
    }
 
    return FALSE;
}
 
复制代码


按照自己的理解改了下后面的判断mime类型的,用真实的类型跟指定允许的类型比较。
刚接触CI框架不久,管理员多多指点

评分

参与人数 1威望 +5 收起 理由
Hex + 5 赞一个!

查看全部评分

 楼主| 发表于 2017-7-13 17:33:43 | 显示全部楼层
Hex 发表于 2017-7-13 17:30
那这样不管你的扩展是 png 还是 jpg 不都可以上传了吗?如果我实际文件是 .php 然后伪装成 .png 怎么办呢 ...

源码再网上看一点:

$ext = strtolower(ltrim($this->file_ext, '.'));

                if ( ! in_array($ext, $this->allowed_types, TRUE))
                {
                        return FALSE;
                }

                // Images get some additional checks
                if (in_array($ext, array('gif', 'jpg', 'jpeg', 'jpe', 'png'), TRUE) && @getimagesize($this->file_temp) === FALSE)
                {
                        return FALSE;
                }

                if ($ignore_mime === TRUE)
                {
                        return TRUE;
                }

                if (isset($this->_mimes[$ext]))
                {
                        return is_array($this->_mimes[$ext])
                                ? in_array($this->file_type, $this->_mimes[$ext], TRUE)
                                : ($this->_mimes[$ext] === $this->file_type);
                }


我觉得呢,
$ext = strtolower(ltrim($this->file_ext, '.'));
应该拿真实的扩展
$ext = strtolower(ltrim($this->file_type, '.'));
 楼主| 发表于 2017-7-13 17:06:56 | 显示全部楼层
Hex 发表于 2017-7-13 16:56
你为什么认为这里应该都用 file_type ?

900行左右

源码:

if (isset($this->_mimes[$ext]))
                {
                        return is_array($this->_mimes[$ext])
                                ? in_array($this->file_type, $this->_mimes[$ext], TRUE)
                                : ($this->_mimes[$ext] === $this->file_type);
                }

按我上面的举例把一个jpg的文件改成png后缀,这里的判断就是
if (isset($this->_mimes['png']))
                {
                        return is_array($this->_mimes['png'])
                                ? in_array('image/jpeg', $this->_mimes['png'], TRUE)
                                : ($this->_mimes['png'] === 'image/jpeg');
                }

这样看你不觉得有问题了吗
发表于 2017-7-13 16:00:36 | 显示全部楼层
这里不只是对比扩展名,会去用 finfo 扩展去判断真实类型,你可以仔细看看源码。
 楼主| 发表于 2017-7-13 16:21:50 | 显示全部楼层
Hex 发表于 2017-7-13 16:00
这里不只是对比扩展名,会去用 finfo 扩展去判断真实类型,你可以仔细看看源码。 ...

就是因为$this->file_type是真实的文件类型,而$ths->file_ext并不一定是真实的文件类型,所以我上面截图那里就出问题了。原来是一张jpg的图片,我把后缀改成png了,$this->file_type是jpg,而$this->file_ext是png,这样比较

return is_array($this->_mimes[$ext])
                                ? in_array($this->file_type, $this->_mimes[$ext], TRUE)
                                : ($this->_mimes[$ext] === $this->file_type);

这段肯定返回false的

发表于 2017-7-13 16:47:20 | 显示全部楼层
niushiluobo 发表于 2017-7-13 16:21
就是因为$this->file_type是真实的文件类型,而$ths->file_ext并不一定是真实的文件类型,所以我上面截图 ...

看了一下,确实感觉不一致,你可以尝试提交 BUG 到官方 github 上。
 楼主| 发表于 2017-7-13 16:51:05 | 显示全部楼层
Hex 发表于 2017-7-13 16:47
你的  CI 是什么版本的?

3.0.0
 楼主| 发表于 2017-7-13 16:52:53 | 显示全部楼层
Hex 发表于 2017-7-13 16:51
看了一下最新的 3.1.5,确实感觉不一致,你可以尝试提交 BUG 到官方 github 上。 ...

我试试拿最新的来试试,多谢你啦
发表于 2017-7-13 16:53:28 | 显示全部楼层

我又仔细看了一下,这里的 file_type 是 mime 类型,而 file_ext 这是文件扩展名,这是两个不同的东西呀。CI 里需要去用文件扩展名找 mime 类型,所以我觉得这里用扩展名没问题。你发现上传有漏洞吗?
 楼主| 发表于 2017-7-13 16:55:06 | 显示全部楼层
Hex 发表于 2017-7-13 16:53
我又仔细看了一下,这里的 file_type 是 mime 类型,而 file_ext 这是文件扩展名,这是两个不同的东西呀。 ...

是两个不同的东西,所以问题不就出在这了么
发表于 2017-7-13 16:56:25 | 显示全部楼层
niushiluobo 发表于 2017-7-13 16:55
是两个不同的东西,所以问题不就出在这了么

你为什么认为这里应该都用 file_type ?
 楼主| 发表于 2017-7-13 17:01:02 | 显示全部楼层
Hex 发表于 2017-7-13 16:56
你为什么认为这里应该都用 file_type ?

file_ext  是扩展名,可以任由人改的,从jpg改成png,改成mp4,改成csv,都是可以的,而file_type又是读真实文件的类型,这两个当然不能比较的

本版积分规则