使<img/> src指向php页面

时间:2014-06-18 16:20:38

标签: php html mysql image

我将所有图像保存在普通用户无法访问的根目录中。我随机生成所有文件名,所以我不希望他们知道文件的路径或名称。目前,我有img元素:

<img src="get_image.php?id=1">

我的get_image.php页面如下:

<?php
include_once 'includes/db_connect.php';
include_once 'includes/functions.php';

$uploaddir = '/root/......./uploads/'; //Direct path from root to folder holding files
$id = $_GET['id'];

if(!is_numeric($id)) {
    die("File id must be numeric");
}

// A QUICK QUERY ON A FAKE USER TABLE
$stmt = $mysqli->prepare("SELECT `name`, `mime` FROM `uploads` WHERE `filmId`=?");
$stmt->bind_param("i", $id); 
$stmt->execute();

$stmt->bind_result($name, $mime);

// GOING THROUGH THE DATA
while($stmt->fetch()) {

    header("Content-Type: " . $mime);
    readfile($uploaddir.$name);
}

?>

如果有的话,我可以这样做吗?我不想直接调用图像文件src:

<img src="../../../uploads/file.jpg"> <!-- I don't want to do this -->

这样做会给用户(或攻击者)一个关于我保存上传文件的位置的提示。这些图像是用户上传的,因此如果攻击者上传带有恶意代码的图像(即使我有大量代码检查和验证文件),他们也不会知道该文件的保存位置。

此外,我是网络开发的新手并保证其安全。如果您有任何提示或指针添加到我必须使我的网页更安全,请随意。谢谢!

我正在使用this link来确保此功能的安全。

解决方案:

而不是:

    header("Content-Type: " . $mime);
    readfile($uploaddir.$name);

我说这个:

    header("Content-Type: " . $mime);
    $contents = file_get_contents($uploaddir . $name);
    echo $contents;

它有效。

4 个答案:

答案 0 :(得分:1)

不仅如此,你可以做到这一点。您甚至可以将<img>指向一个似乎是图像路径的PHP脚本。例如:

<img src="phpimages/my_image.png" />

这个技巧需要一个Apache HTTP服务器(你无疑会使用它)和mod_rewrite插件(你确定已安装)。 您可以将.htaccess文件放在/phpimages/中,其中包含以下内容:

RewriteRule ^([^\.]+)\.(png|jpg|gif)$   /image.php?file=$1.png [NC,L]

如果您只想要用户ID,可以将正则表达式限制为:

RewriteRule ^([0-9]+)\.(png|jpg|gif)$   /image.php?file=$1.png [NC,L]

进一步解释了此过程here

在脚本image.php(在同一目录中)中,然后将文件名作为字符串,例如:

$filename = $_GET["file"];  //eg.: "file1.jpg"

不要忘记过滤../次黑客攻击。要将文件打印给用户,只要它确实存在,请使用readfile

const REAL_AVATAR_PATH = "../../../uploads/"
if(file_exists(REAL_AVATAR_PATH.$username)) {
     header("Content-Type: image/jpg");  //For simplicity, I have ommited to send different header for different images as "png", "gif" and so on.
     readfile(REAL_AVATAR_PATH.$username);
}
else {
     header("HTTP/1.0 404 Not Found");
     die("Error 404 - sorry");
}

在您的情况下,您可以将路径设为/avatars/[number].png(并将所有图片转换为png)。

答案 1 :(得分:1)

而不是:

header("Content-Type: " . $mime);
readfile($uploaddir.$name);

我说这个:

header("Content-Type: " . $mime);
$contents = file_get_contents($uploaddir . $name);
echo $contents;

它有效。

答案 2 :(得分:0)

我不同意目前的答案。如果您正在查看数据库,那么您可以轻松地执行以下操作:

<img src="/phpimages.php?id=23" alt="{ALT}" />
然后

phpimages.php将获取ID 23并输出该文件。你的最终用户不知道图像来自哪里;他们甚至可以来自另一台服务器。此选项还允许更易读的代码,同时仍保持相同的安全性。

<img src="/phpimages.php?frontImage" alt="{ALT}" />

现在,您只需使用下面链接中描述的内容,即可获得第一个$ _GET关联的密钥。或者您可以将其设为id=frontImage,然后使用$_GET['id']

Get first key in a (possibly) associative array?

答案 3 :(得分:-1)

在PHP文件中,您需要将标题内容类型设置为

 header('Content-Type: image/png');

以便浏览器知道get_image.php将图像作为响应

让临时图像的路径存储在$ path

<?php
$im = imagecreatefrompng($path);

header('Content-Type: image/png');

imagepng($im);
imagedestroy($im);
?>