3

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

任何建议表示赞赏。

4

3 回答 3

1

您可以使用exif_imagetype()它来查看它是否是图像。

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

于 2013-04-16T17:22:21.557 回答
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);
于 2013-04-16T17:34:58.780 回答
0

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

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

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

于 2013-04-16T17:35:38.110 回答