2

我正在构建一个允许登录用户上传产品图片的小型网络应用程序。我正在尝试正确构建,并且在过去一些天真的实施之后,决定将所有上传的内容添加到我的公共文件夹中。

\app (public folder)
-\index.php
\includes
\config
\uploads

这将使得如果恶意用户设法上传 PHP 文件,服务器将无法访问或提供该文件。

话虽如此,我将如何在网页上提供这些图片?做这个的最好方式是什么?过去,我使用了一个 getImage.php 文件,该文件将采用一个 ID 参数(以及一些生成值的哈希值以避免用户只是猜测 ID),它看起来像“getImage.php?id=555&c=44j54k3h5”。服务器抓取数据库中的图像信息(真实路径)并加载内容,重建头部,并发送图像。

这种方法是否存在任何安全问题?有没有办法让它更漂亮?有一个查找 /images/imagename.jpg 并将它们发送到我的 getImage.php 文件的 htaccess 重写规则会添加安全漏洞吗?任何关于最佳实践的建议将不胜感激。

4

3 回答 3

3

看看这堂课。它将处理上传,进行安全检查并为您煮咖啡:)

http://www.verot.net/php_class_upload.htm

于 2012-05-31T18:21:31.490 回答
1

您提供上传图片的方法的安全性确实取决于许多其他因素。

  • 上传时如何处理和保护图像/文件?上传的目录/文件权限是什么?
  • 哪些进程有权读取和写入这些位置?
  • 你有什么类型的文件处理程序可以执行任意文件?
  • 如果您要使用 PHP->get_image->display_image 路由,它是否会在上传后尝试防止恶意意图(在 getimage 上?)

我会使用Apache mod_alias来引用 webroot 上面的目录。这样,您仍然可以使用指向图像的链接,而无需打开完整的以上根目录来暴露。

于 2012-05-31T18:25:50.110 回答
1

“更漂亮”的方法是使用.htaccess重定向

RewriteEngine On                                                                                                                                                                                                                                  
RewriteBase /                                                                                                                      
RewriteRule ^getImage/([0-9]+)/(.+)\.png$ getImage.php?id=$1&c=$2 [NC,L]

然后在getImage.php

if (isset($_GET['id']) && isset($_GET['c'])) {

    // set headers
    header("Content-Type: image/png");

    // cache control
    header("Cache-Control: private, max-age=10800, pre-check=10800");
    header("Pragma: private");
    header("Expires: " . date(DATE_RFC822, strtotime("2 day")));
    if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
            header('Last-Modified: ' . $_SERVER['HTTP_IF_MODIFIED_SINCE'], true, 304);                                    
            exit;                            
    }

    /* do things */
    imagepng($image_resource);
    imagedestroy($image_resource);
}
else {

    echo "bad request";
}

所以而不是

site.com/getImage.php?id=555&c=44j54k3h5

你会用

site.com/getImage/555/44j54k3h5.png

这种方法没有任何额外的安全风险或漏洞。只需确保您的 get 变量在查询之前被转义以避免注入攻击。

如果您想保护自己免受恶意文件上传的侵害,则需要在服务之前执行此操作。

于 2012-05-31T18:37:40.550 回答