在root之外存储图像时的安全逻辑

时间:2015-04-17 08:31:27

标签: php image apache encryption

我有一个社交网络,用户可以使用嵌入式图片创建帖子。图像存储在文档根目录之外。当请求查看页面时,我想发送包含<img>属性的src元素的普通HTML响应。问题是,如何有效地保护图像,以便只有授权用户才能查看它们?

网络背后的权限系统非常复杂。社交图具有几种不同类型的节点和边缘,并且用户浏览内容的权限取决于该图。我会在每个页面请求中查询用户的子图一次,以检索允许的内容列表,但我不想再为每个图像查询它。这是一项昂贵的练习,有些页面可能有50张或更多的图像。

因此,据我所知,当我为页面提供服务时,我需要发送一个或多个密钥,当与服务器的数据结合使用时,它将解锁&#39;图片。这是我的意思的一个例子 - 在示例中,我将一个键放在一个url中,其中url是图像的src属性:

http://example.com/images?id=1234_my_image_id&key=1234123412341234FFF

在此实现中,我传递一个唯一标识图像的参数。我需要这样做,因为我不想进入转换表或用户特定的转换表(因为复杂性和性能)。我还发送了一个&#39;图像键&#39;。

我的想法是,用户的会话将包含会话密钥&#39;。当服务器收到图像的GET时,它会将会话密钥添加到请求的图像文件名并对其进行哈希处理(就像密码+盐一样)。如果哈希的结果等于图像密钥,我将从磁盘检索图像并发送它。

这个问题是,如果一个黑客获取了一个图像URL,他们有一个输入到哈希(即图像键),以及哈希所需的输出(即图像文件名),所以他们可以(使用彩虹表)向后工作以获得潜在会话密钥列表。然后,通过一系列请求和消除过程,他们可以建立准确的会话密钥。

那么,我该如何解决这个问题呢?我可以使用每个请求更改会话密钥,但这意味着图像网址会随着每个请求而改变,因此不会有图像缓存。

我确定我不是第一个遇到此问题的人。是否有共同的&#39;解决问题的方法? (我找不到这样的事情)。我可以考虑对页面响应中的图像进行base64编码,但我猜这会产生性能成本。

仅供参考 - 我使用的是PHP和Apache。我使用url重写来整理一些东西。

2 个答案:

答案 0 :(得分:0)

嗯,我的想法和你一样。因此,获取图像id +用户密码,制作一个hashetvoilâ。你有一个易于使用的系统。

但你遇到的问题主要是彩虹表。因此可以解决这个问题;

  • bcrypt并且像真正的密码一样
  • 使它成为一个时间敏感的秘密,所以这个秘密只有30秒有效,这可能就像hash(hash(secret + time) + secret)一样简单,虽然现在你必须发送用它进行哈希处理的时间,所以不多还有一个秘密

我想到的其他解决方案

  • 使用图片保存允许的用户列表,权限更改+上传更新此列表
  • 您可以创建一个函数displayImage(id),它的作用是呈现<img src="url" />,但在后台它会设置一个标志x秒,以允许用户访问该图像。

答案 1 :(得分:0)

将图像存储在根目录之外后,查看它们的唯一方法是让代码访问它们。在PHP中,该代码看起来像......

$file_location = '../../images/' . $some_id_that_is_authenticated_and_cleansed_for_slashes . '.jpg';

readfile($file_location);  // grabs file and shows it to user