douqilin4296 2014-01-02 10:24
浏览 69
已采纳

在PHP中使用regex过滤掉有效的文件名

I have a PHP website where registered users can upload an avatar. One of the restrictions is that people can only upload either a .jpg or .jpeg file with only alphanumeric characters, anything else is rejected. This is to make sure I only get uploads like "avatar.jpg", and not "evilcode.php" or "secretcode.php.jpg". I'm also planning other checks, but right now I can't get this first step to work.

I am using this regex expression:

[a-zA-Z0-9]{1,150}+\.+(jpe?g)

This is the code I'm currently using. The function is called from another php file, with $_FILES['avatar'] as a parameter.

public function updateAvatar($avatar)
{
    $regex = '^[a-zA-Z0-9]{1,100}+\.+(jpe?g)$';
    $name = $avatar['name'];    
    $result = preg_match_all($regex, $name);
    if($result === 1)
    {
        return true;
    } else
    {
        return false;
    }
}

This always returns false, when uploading either "avatar.jpg", "code.php", or "duck.gif". According to the PHP manual, this code should be correct. The method returns either an integer or a boolean, and warns that you should use ===, not == to compare the result. Does anyone know what I did wrong?

  • 写回答

5条回答 默认 最新

  • douqiao2008 2014-01-02 10:38
    关注

    When you check yours incoming file through regex, it is possible to upload the exploit file with executable mime, so you must check mime of the file for safe uploading:

    public function updateAvatar($avatar)
    {
        $available_mimes = array(
            'jpeg' => 'image/jpeg',
            'jpg' => 'image/jpg',
            'iejpg' => 'image/pjpeg' // this mime sent Internet Explorer for jpg files
        );
    
        if(in_array($avatar['type'], $available_mimes)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    

    As for your regex function:

    public function updateAvatar($avatar)
    {
        // Use regex with ignore case flag (for validating jpg and JPG)
    
        // Uncomment next line, if you want to check files with "_" symbols at name
        // if(preg_match('/^(\w+)\.(jpe?g)$/i', $avatar['name']))
    
        if(preg_match('/^([a-z0-9]+)\.(jpe?g)$/i', $avatar['name']))
        {
            return true;
        } 
        else
        {
            return false;
        }
    }
    

    And try to use preg_match()

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊
  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟
  • ¥15 树莓派控制机械臂传输命令报错,显示摄像头不存在
  • ¥15 前端echarts坐标轴问题
  • ¥15 ad5933的I2C