存储和读取public_html上方的图像

时间:2009-09-12 19:57:54

标签: php html security filesystems

我正在尝试保护我的PHP图像上传脚本,并且我必须跳过的最后一个障碍是使用户不能直接执行图像,但服务器仍然可以在网页中提供它们。我尝试更改文件夹的所有权和权限无济于事,因此我尝试将图像存储在public_html上方并将其显示在存储在public_html中的页面中。

我的文件结构:

 - userimages
   image.jpg
   image2.jpg

 - public_html
   filetoserveimage.html

我尝试链接到userimages文件夹中的图像,如下所示:

<img src="../userimages/image.jpg">

但它不起作用。这里有什么我想念的吗?如果您有任何更好的建议,请告诉我。我试图阻止公共用户执行他们可能上传的潜在危险文件。就像一个额外的安全措施。谢谢!

6 个答案:

答案 0 :(得分:4)

你想要的东西基本上是不可能的。

浏览器加载页面的方式(在非常基本的意义上)是这样的:

第1步:下载页面。 第2步:解析页面。 第3步:下载页面内容中引用的任何内容(图像,样式表,javascripts等)

每个“下载”事件都是原子的。

您似乎只想向刚下载了引用这些图片的网页的用户提供图像。

正如PHP Jedi所说,你可以通过PHP传递文件。您可以扩展他的代码,并检查请求上的HTTP_REFERER,以确保人们不会“只是”抓取图像。

现在,通过PHP passthru脚本提供每个图像效率不高,但它可以工作。

人们想要这样做的最常见原因是避免“热链接” - 当人们在引用服务器上的图像的其他网站上创建图像标签时。当他们这样做时,您会花费资源处理请求,这些请求会在其他人的页面上显示。

如果这是你真正想要避免的,你可以使用mod_rewrite来检查引用者。

可以找到关于热链接/反链接的体面讨论here

答案 1 :(得分:3)

使用图像中继脚本!

要提供public_html文件夹之外的图像文件,您必须通过php脚本执行此操作。例如,制作一个image-relay.php来读取公共html之外的图像...

<?php
header('Content-Type: image/jpeg');
$_file = 'myimage.jpg'; // or $_GET['img']
echo file_get_contents('/myimages/'.$_file);
?>

现在,$ _file可能是一个$ _GET参数,但是它的绝对值对于验证输入参数很重要...

现在你可以让<img src="image-relay.php?img=flower.jpg">访问位于/myimage/flower.jpg中的flower.jpg图片......

答案 2 :(得分:1)

嗯,网络浏览器只能访问public_html中的文件和文件夹。

答案 3 :(得分:1)

如果public_html目录是您的用户服务器的根目录,那么Apache无法提供任何不在该目录内/下的内容。

如果您希望Apache直接提供文件,则必须将其放在public_html下面。

答案 4 :(得分:1)

我认为您的误解在于,如果您在<img>标记中包含图片,您的浏览器会向网络服务器发送完全相同的请求以获取它,如果您将其发送到网络服务器尝试直接在浏览器中打开图片的src网址。

因此,要么两件事都有效,要么两者都没有。

周围有黑客攻击,涉及(php或其他)脚本,以确保请求图像的IP在过去几秒内也请求了html页面(如果用户位于代理后面,这将无效)转动传出的IP)或通过检查引用(它不适用于HTTP,如果用户禁用了引用,也没有。)

如果你想确保只有一些用户可以看到图像(通过<img>标签和直接),你可以将图像放在public_html之外,并有一个(php或其他)脚本来验证用户的提供图像之前的凭据。

答案 5 :(得分:1)

如果您使用的是Apache或lighttpd,您可以使用X-Sendfile标头发送不在Web根目录中的文件(前提是您没有更改mod_xsendfile的配置)。

要了解有关X-sendfile的更多信息,请参阅此site

此解决方案为您提供最佳性能,因为PHP不发送文件但服务器发送,因此可以在提供文件时退出PHP。

希望有所帮助。