草庐IT

php - 将上传的图像放在公共(public)文件夹中是否安全?

coder 2023-06-15 原文

我刚刚和我的队友讨论了用户上传图片在图片库中的位置。我想更广泛地了解我们建议的方法。

我的队友编写了一个 Controller + 操作,它调用 file_get_contents 放置在不可用于公共(public)浏览的文件夹中的图像文件(即,在服务器上的 public_html 之外) , 并通过标题回显它。这是安全的,但由于我们使用 Zend Framework,它的爬行速度也很慢 - 由于执行 Bootstrap 的查询,每次调用图像 Controller 都会花费我们大约 500 毫秒的延迟。这很烦人,因为图片库 View 同时显示 20 多张图片。

简而言之,相关代码是:

class ImageController extends Zend_Controller_Action {
    public function showAction () {
        $filename = addslashes($this->_getParam('filename'));
        if(!is_file($filename)) {
            $filename = APPLICATION_PATH.'/../public/img/nopicture.jpg';
        }
        $this->_helper->viewRenderer->setNoRender(true);
        $this->view->layout()->disableLayout();
        $img = file_get_contents($filename);
        header('Content-Type: image/jpeg');
        $modified = new Zend_Date(filemtime($filename));
        $this->getResponse()
             ->setHeader('Last-Modified',$modified->toString(Zend_Date::RFC_1123))
             ->setHeader('Content-Type', 'image/jpeg')
             ->setHeader('Expires', '', true)
             ->setHeader('Cache-Control', 'public', true)
             ->setHeader('Cache-Control', 'max-age=3800')
             ->setHeader('Pragma', '', true);
        echo $img;
    }
}

然后,在 View 中,我们只需调用:

<img src="<?php echo $this->url(array('controller' => 'image', 'action' => 'show', 'filename' => PATH_TO_HIDDEN_LOCATION.'/filename.jpg')); ?>" />

我有一个不同的方法:我更喜欢将原始图像保存在一个隐藏的位置,但是一旦被请求,就将它们复制到一个公共(public)位置并提供一个链接(有一个额外的机制,由 cron 运行,为了不浪费空间,不时地删除公共(public)图像目录,以及 robots.txt 告诉 Google 不要索引该目录)。该解决方案将文件(每个给定时刻一些文件)放在一个可公开访问的目录中(前提是知道文件名),但也只需要一个 View 助手,因此不需要启动 Bootstrap :

class Zend_View_Helper_ShowImage extends Zend_View_Helper_Abstract {
    public function showImage ($filename) {
        if (!file_exists(PUBLIC_PATH."/img/{$filename}")) {
            if (!copy(PATH_TO_HIDDEN_FILES."/{$filename}",PUBLIC_PATH."/img/{$filename}"))
                $url = PUBLIC_PATH.'/img/nopicture.jpg';
            else
                $url = PUBLIC_PATH."/img/{$filename}";
        } else {
            $url = PUBLIC_PATH."/img/{$filename}"
        }
        return "{$url}";
    }
}

有了这个helper的帮助, View 中的调用就很简单了:

<img src="<?php echo $this->showImage('filename.jpg'); ?>" />

问题:我的方法是否像我同事所说的那样构成安全威胁?这有哪些潜在风险?而且,最重要的是,安全威胁(如果有的话)是否超过页面加载 10 秒的增益?

以防万一:我们正在开发一个拥有大约 15,000 名注册用户的社区门户网站,画廊是一个非常常用的功能。

*我粘贴的代码是我们每个人提出的经过编辑的简化版本 - 只是为了展示这两种方法的机制。

最佳答案

I have a different approach: I prefer to keep the original images in a hidden location, but as soon as they are requested, copy them to a public location and provide a link to it

创造力+1。

Does my approach pose a security threat, as my coleague states? What are the potential risks of this? And, most importantly, do the security threats, if any, outweigh the 10 seconds gain on page load?

有点。是的,如果您有只允许某些人看到的图像,并且您将它们放在一个可公开访问的目录中,那么其他人可以看到该图像就会发生变化,这似乎是不可取的。我也不认为(可能是错误的)它会在页面加载时增加 10 秒,因为您必须复制图像,这是一个相当密集的操作,比使用 file_get_contents 或 readfile( ) 还要多。

This is secure, but since we use Zend Framework, it's also crawling slow - each call to the image controller costs us approx 500ms of lag due to the bootstrap's queries being executed.

如果我可以建议;针对此特定案例的 nuke Zend Framework。我也在为一个相当大的网站使用 Zend Framework,所以我知道 Bootstrap 可能需要比你想要的更长的时间。如果您绕过 Zend Framework,选择 vanilla PHP,这将显着提高性能。

此外,使用 readfile(),而不是 file_get_contents()。一个很大的区别在于 file_get_contents 会在输出之前将整个文件加载到内存中,而 readfile 执行此操作的效率更高。

关于php - 将上传的图像放在公共(public)文件夹中是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6622854/

有关php - 将上传的图像放在公共(public)文件夹中是否安全?的更多相关文章

  1. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  2. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  3. ruby-on-rails - 添加回形针新样式不影响旧上传的图像 - 2

    我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司

  4. c - mkmf 在编译 C 扩展时忽略子文件夹中的文件 - 2

    我想这样组织C源代码:+/||___+ext||||___+native_extension||||___+lib||||||___(Sourcefilesarekeptinhere-maycontainsub-folders)||||___native_extension.c||___native_extension.h||___extconf.rb||___+lib||||___(Rubysourcecode)||___Rakefile我无法使此设置与mkmf一起正常工作。native_extension/lib中的文件(包含在native_extension.c中)将被完全忽略。

  5. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  6. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  7. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

  8. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  9. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  10. ruby-on-rails - 在 heroku 的 .fonts 文件夹中包含自定义字体,似乎无法识别它们 - 2

    Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在

随机推荐