安全存储私人图像

时间:2014-05-17 14:10:12

标签: php image .htaccess security

我需要一个安全的解决方案来存储仅由特定用户访问的更大(未知)数量的私有图像。这个问题不包括登录,会话或其他类似的事情 - 仅围绕图像并存储它们。

我开始解释我想要实现的目标,然后继续我想到的事情。

私人图片只能由特定用户访问

用户登录我的网站上传和查看他/她提供和上传的图片。图像只能由该用户访问 - 因此需要登录。请求查看图像时,渲染由PHP脚本处理,验证用户的权限并从安全目录中提取实际图像。

我所知道的,假设和思考。

为便于管理而对图像编制索引

上传的每张图片都会在数据库中编入索引进行管理,即

Title: "Me on a scooter"
User: {0E4A759A-CC31-4B0D-97E1-EEFB28F0BF86}
Filename: asuohLAFUUHJSFUhaSGFUOAHSGUA
Extension: .jpg

当用户想要查看图像时,服务器会验证并检查用户是否确实是图像的所有者。

让公众远离图像

我已经阅读了一些文章,解释了将文件保留在文档根目录之外的良好做法。虽然我理解这个概念,但我并不完全明白如何在实践中做到这一点。我的假设:

/var/www/myFolder/ //here's where the html files are stored
/mySecureFolder/ //here's where the content are stored outside of the root, or on a higher level

因此,只要服务器显示图像,它就会在/ mySecureFolder /中查找它,并在为用户呈现文件之前检查该文件是否存在。

假设#2

创建并放置一个.htaccess文件,阻止除了/ mySecureFolder /中的localhost之外的所有人,我应该做些什么来阻止其他人。

问题#1 PHP进程作为用户www-data运行,是否可以安全地建立/ mySecureFolder / www-data的所有者组?

假设#3 - Chmod

要允许除一个特定系统用户以外的任何用户,我应该使用0770 recursiv CHMOD该文件夹,只允许所有者用户和所有者组读取,写入和执行权限。

问题#2

使用.htaccess拒绝访问除了localhost之外的所有人,但相当于将安全文件夹放在root(/ var / www / myFolder /)文件夹之外?

假设#4 Overkill

加密存储在文件系统上的每个图像都是过度的,如果目录权限设置正确则不必要。

我的攻击场景只是外部攻击,黑客无法通过SSH访问服务器,也无法通过物理访问服务器。因此,可能的攻击是来自我创建的代码的外部攻击 - 如注射等。

我希望未来的旁观者可能会得到可能的答案,因此如果您帮我格式化这个问题以确保其尽可能清晰,我将不胜感激。

2 个答案:

答案 0 :(得分:3)

最好的方法是将图像存储在/ www之外 - 并将它们放在自己的目录中。

然后使用readfile()来提供服务'图像给授权用户。无需CHMOD或使用htaccess等 - 因为它位于www文件夹之外,除非通过您的应用程序,否则无法访问。

这样的事情会起作用:

function show_image($file_name= "")
{
    // Ensure no funny business names to prevent directory transversal etc.
    $file_name = str_replace ('..', '', $file_name);
    $file_name = str_replace ('/', '', $file_name);

    // now do the logic to check user is logged in - put your own code here
    if (LoggedInUserCanAccessThisFile())
    {
        // Serve file via readfile()
        // Images are stored in a specific user folder - so only the own user can get their own images
        readfile('../image_storage/' . getLoggedInUserID() . '/' . $file_name);
    }
}

您可以阅读有关readfile() here from php.net

的更多信息

答案 1 :(得分:1)

我正在研究类似的问题;但是,我可能会改变我的逻辑以合并readfile()函数。但是现在,我将图像放在公共html文件夹之外的安全文件夹中。 php脚本将目录读取到会话数组,然后按文件名对其进行排序。第二个脚本使用html来导航文件名数组。选择文件后,会将其复制到tmp公共图像目录并通过html显示。在选择下一个文件之前,将从tmp目录中删除前一个文件。原始文件保留在安全文件夹中。这可能有点尴尬,但对我来说效果很好。