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 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持