Безопасно ли размещать загруженные изображения в общей папке ?

Я только что обсудил со своим товарищем по команде расположение загруженных пользователем изображений в галерее изображений. Я хотел бы получить более широкое представление о методах, которые мы предлагаем.

Мой товарищ по команде написал контроллер + действие, которое вызывает file_get_contents для файла изображения, помещенного в папку, недоступную для публичного просмотра (т. Е. Вне public_html на сервере) и отображает его через заголовок. Это безопасно, но, поскольку мы используем Zend Framework, сканирование выполняется медленно - каждый вызов контроллера образа стоит нам примерно 500 мс задержки из-за выполняемых запросов начальной загрузки. Это раздражает, поскольку в представлении галереи изображений одновременно отображается более 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;
    }
}

Затем в представлении мы просто вызываем:

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

У меня другой подход: Я предпочитаю хранить исходные изображения в скрытом месте, но как только они будут запрошены, скопируйте их в общедоступное место и предоставьте ссылку на него (с дополнительным механизмом, запускаемым cron, чтобы каждый раз стирать каталог общедоступных изображений а затем, чтобы не тратить впустую место, и robots.txt , говорящий Google не индексировать каталог). Решение помещает файлы (по несколько в каждый данный момент) в общедоступный каталог (при условии, что кто-то знает имя файла), но также требует только помощника представления, таким образом, не запускает загрузочную программу:

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}";
    }
}

С помощью этого помощника вызов очень прост в представлении:

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

Вопрос: Представляет ли мой подход угрозу безопасности, как заявляет моя коллега? Каковы потенциальные риски этого? И, что наиболее важно, перевешивают ли угрозы безопасности, если таковые имеются, 10-секундный выигрыш при загрузке страницы?

В случае, если это имеет значение: мы работаем над порталом сообщества, где зарегистрировано около 15 тысяч пользователей, при этом галереи очень часто используемая функция.

* Код, который я вставил, представляет собой отредактированную, упрощенную версию того, что придумал каждый из нас, просто чтобы показать механику обоих подходов.

16
задан mingos 8 July 2011 в 09:59
поделиться