用php保存图像文件?

时间:2014-08-21 11:53:22

标签: php image

我在root中有这个代码,当用户点击链接

时自动保存图像文件
<?
// Force download of image file specified in URL query string and which
// is in the same directory as this script:
if(!empty($_GET['file']))
{
  $filename = $_GET['file']; // don't accept other directories
  $size = @getimagesize($filename);
  $fp = @fopen($filename, "rb");
  if ($size && $fp)
  {
    header("Content-type: {$size['mime']}");
    header("Content-Length: " . filesize($filename));
    header("Content-Disposition: attachment; filename=$filename");
    header('Content-Transfer-Encoding: binary');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    fpassthru($fp);
    exit;
  }
}
header("HTTP/1.0 404 Not Found");
?>

问题

  1. 黑客可以将任何字符串发送到此文件并保存我的根文件吗? (例如:index.php或者其他......)

  2. 如何查看包含图片文件的网址?

3 个答案:

答案 0 :(得分:1)

Q1:您应该只限制对特定目录的访问 - 如果这只是一个目录,那么您无需使用$_GET请求提供的目录,只需将其包含在您的php中即可。< / p>

$filename = end( explode( '/', $_GET['file'] ) );
$filename = '/uploadsdirectory/' . $filename;

Q2:要检查所请求文件的扩展名,您应该执行以下操作:

$extension = end( explode( '.', $filename ) );

这将返回jpgpng等。基本上是最后一段时间之后的任何内容

答案 1 :(得分:1)

使用exif_imagetype

int exif_imagetype ( string $filename )

答案 2 :(得分:0)

这是您需要白名单方法的事情。如果您的所有图片都存储在同一个文件夹中,只需传递文件名(例如image.jpg),不要显示任何路径,并禁止出现任何/

下面的is_scalar()检查会检查有人没有?file[]=test,这会将数组发送到服务器。这有时不是什么大问题,但它可能会导致我们不想要的服务器输出错误。

if (!empty($_GET['file']) && is_scalar($_GET['file'])) {
    $filename = $_GET['file'];
    if (strpos('/', $filename) !== false) {
        exit;
    }

然后我们可以查看文件扩展名并确定是否允许。请注意strtolower()的使用,以便它匹配大写扩展(PNGJPG等)。检查$ext != $filename确保没有人只是将“jpg”或“png”作为文件名传递。

    $allowed_types = array('png', 'jpg', 'jpeg', 'gif');
    $ext = preg_replace('/^(.*\.)(.*?)$/', '\\2', $filename);
    if (!in_array(strtolower($ext), $allowed_types) && $ext != $filename) {
        exit;
    }

最后,检查文件是否确实存在,并且确实是文件。 file_exists()也匹配目录,因此我们也可以通过is_file()检查来确定。

    $filename = '/images/' . $filename;
    if (!file_exists($filename) || !is_file($filename)) {
        exit;
    }

完成这些检查后,您确定$filename正常,您可以开始执行以下操作(从您的代码中获取):

$size = @getimagesize($filename);