如何判断URL是否指向图像?

时间:2013-04-16 17:19:05

标签: php

我有一个带有文本输入的php页面,用户应该粘贴图像的远程URL,我必须将其存储在服务器中并显示给用户。现在的问题是,我不相信用户总是会提供一个正确的图片网址,我不希望他们上传一个pdf或其他文件,或者一个巨大的,几个gb的文件。现在我可以检查扩展,但这不是很有帮助,我听说我可以检查mime类型,但我不知道如何打开文件一次并检查所有验证,如mime-type和file一次性大小,然后复制文件。此外,由于文件将按原样提供(稍有名称更改),我想知道是否可以确保该文件没有任何注入的病毒或有问题的代码。

任何建议表示赞赏。

3 个答案:

答案 0 :(得分:1)

您可以使用exif_imagetype()查看其是否为图片。

如果你想100%确定它不是恶意软件或奇怪的东西。最好使用GD库并通过GD库保存。所以内部没有dangerous代码。

答案 1 :(得分:0)

使用Curl,您可以使用https存在任何问题,您可以存储文件并进行检查 下面是检查图像内容类型的代码,然后使用exif_imagetype()检查文件(启用php_mbstring和php_exif扩展)。

$url = 'https://www.google.com/images/icons/ui/doodle_plus/doodle_plus_google_logo_on_grey.gif';

$userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';       
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_exec( $ch ) ;
if(!curl_errno($ch))  
{
    $type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); 
    if ( stripos($type, 'image') !== FALSE )
    {
        curl_setopt($ch, CURLOPT_NOBODY, false);  
        curl_setopt($ch, CURLOPT_HEADER, false);    
        $filename = tempnam('/path/to/store/file/', 'prefix');
        $fp=fopen($filename,'wb');
        curl_setopt($ch, CURLOPT_FILE, $fp); 
        curl_exec($ch);
        fclose($fp);
        if ( exif_imagetype($filename) !== FALSE )
        {
            echo "100% IMAGE!";
            // take it!
        }

        unlink($filename);
    }      
}

curl_close($ch);

答案 2 :(得分:0)

这里有很多事情可以做。我建议使用cURL作为传输文件的机制(而不是file_get_contents()或类似的)。这样做的原因是您可以先对资源发送HEAD请求,以便在提交实际下载之前获取标头信息。从标题中,您应该能够评估文件名,文件大小,mime类型信息等。请注意,此信息的任何信息都应该是可信的,但它至少会在提交文件下载之前进行健全性检查。

完成完整性检查后,您可以将文件下载到本地snadbox目录中。这不应该是Web可访问的目录。您可以使用exif_imagetype()来确定文件是否确实是您感兴趣的类型的图像。

假设这一切看起来都不错,我会做最后一点清理 - 并在GD库中重命名(也许使用imagecreatefrom*()函数从临时下载文件制作最终图像。)