0

可能重复:
确定 URL 是否是 PHP 中的图像的最佳方法

编辑:

我有一个脚本,它使用 file_get_contents (我的主机允许)将远程文件复制到我的服务器,让用户共享图片。但是,为了避免滥用,我需要代码来检查文件的大小、有效性(以及在我的服务器上允许它们之前的恶意代码。到目前为止,我一直无法找到一个强大的解决方案。其他人指出的旧文章,例如这个:

https://stackoverflow.com/questions/676949/best-way-to-determine-if-a-url-is-an-image-in-php

建议可能的方法——检查文件扩展名、mime 类型并在文件在服务器上之后使用 GD,但请注意,没有一个是万无一失的。然而,无数站点允许远程上传文件,这表明必须有一些更好的方法来处理安全问题。

File_get_upload 是最基本的。卷曲很粗糙,但可能具有更多功能。如果文件不是图像,GD 的 get_image_size 函数将返回 false,如下所示:

$imginfo_array = getimagesize($tempFile); 

但是,我的理解是 GD 无法远程处理文件。

这是此阶段使用 file_get_contents 的简单代码:

$url = 'http://example.com/image.php';
$img = '/my/folder/flower.gif';
file_put_contents($img, file_get_contents($url));

这是卷曲版本:

$ch = curl_init('http://example.com/image.php');
$fp = fopen('/my/folder/flower.gif', 'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
fclose($fp);

有谁知道在您的服务器上检查文件大小和有效性的最佳实践?

4

1 回答 1

1

我真的不认为使用stream_get_meta_data, header informationor , extensionormime information是最好的解决方案......为什么?

已经创建了一个假的 PNG 图像,你会看到

  • 假哑剧
  • 假创作日期
  • 假修改日期
  • 假文件扩展名

缺少功能

  • 假输出
  • 假尺寸

情况1

$fake = "http://i.stack.imgur.com/wbSmq.png";
$meta = stream_get_meta_data(fopen($fake, 'rb'));
var_dump($meta);

输出

array (size=10)
  'wrapper_data' => 
    array (size=12)
      0 => string 'HTTP/1.0 200 OK' (length=15)
      1 => string 'Accept-Ranges: bytes' (length=20)
      2 => string 'Cache-Control: max-age=315360000' (length=32)
      3 => string 'Content-Type: image/png' (length=23)
      4 => string 'Date: Mon, 03 Dec 2012 10:41:08 GMT' (length=35)
      5 => string 'ETag: "add48f1871182328f5d8ebe74c1df32d"' (length=40)
      6 => string 'Expires: Thu, 31 Dec 2037 23:58:38 GMT' (length=38)
      7 => string 'Last-Modified: Mon, 03 Dec 2012 10:29:40 GMT' (length=44)
      8 => string 'Server: ECAcc (cdg/44CF)' (length=24)
      9 => string 'X-Cache: HIT' (length=12)
      10 => string 'Content-Length: 167' (length=19)
      11 => string 'Connection: close' (length=17)
  'wrapper_type' => string 'http' (length=4)
  'stream_type' => string 'tcp_socket/ssl' (length=14)
  'mode' => string 'rb' (length=2)
  'unread_bytes' => int 167
  'seekable' => boolean false
  'uri' => string 'http://i.stack.imgur.com/wbSmq.png' (length=34)
  'timed_out' => boolean false
  'blocked' => boolean true
  'eof' => boolean false

从上面的输出中没有任何迹象表明图像是假的

案例2

据我所知,我不能直接在远程 url 上使用 GD。

这不是真的getImageSize是一个 GD 函数可以与远程 URL 一起使用,并且它更可靠地识别假图像。

$fake = "http://i.stack.imgur.com/wbSmq.png";
$meta = getimagesize($fake);
var_dump($meta);

输出

array (size=6)
  0 => int 1                     |
  1 => int 1                     |=----------------- Looks Fake
  2 => int 3                     |
  3 => string 'width="1" height="1"' (length=20)
  'bits' => int 1   <------------------------------- fake
  'mime' => string 'image/png' (length=9) ---------- mime may be correct 

如果The goal here is to let users share valid pictures up to a certain size正如您所提到的使用getImagesize更可靠的解决方案

于 2012-12-03T10:47:20.020 回答