Безопасная загрузка произвольных файлов на многопользовательском сайте drupal

Drupal часто используется на многопользовательских сайтах, на которых требуется обеспечить возможность загружать произвольные файлы через файловый менеджер. Однако, если пользователям разрешать загружать произвольные файлы, то они могут попытаться атаковать других посетителей сайта, произвести накрутку голосов, перехватить куки и много других неприятных вещей за счет загрузки своего кода javascript или вставки своих html-страниц.
Казалось бы, можно запретить загружать файлы с расширением js или html, но
1) этого может оказаться недостаточно
2) самый популярный файловый менеджер под drupal - IMCE, не умеет запрещать загрузку файлов по расширению, а может только разрешать либо все, либо определенные расширения.

Наиболее надежной защитой на многопользовательском сайте будет использование другого домена для отдачи загруженный файлов. Т.е. пользователь авторизуется и загружает файл на сайте www.example.com, но файл реально раздается не с www.example.com, а с user.example.com.

Пусть мы настроили IMCE так, чтобы загруженные пользователем username файлы попадали в локальную папку /var/www/vh/www.example.com/sites/default/files/username и на сайте их адрес будет http://www.example.com/sites/default/files/username.
Для этого надо в настройках профиля IMCE (admin/config/media/imce/profile/edit/2 и admin/config/media/imce/profile/edit/1) в директории указать php: return $user->name; в качестве директории пользователя:


Теперь настроим веб-сервер, чтобы все запросы на файлы из папки sites/default/files/username он перенаправлял на http://user.example.com/username. За счет этого пользовательский код на user.example.com не получит доступа к кукам основного  www.example.com.


Для отдачи статики я использую nginx. Вот кусок конфигурации для него:
server {
    listen www.example.com:80;
    server_name www.example.com;
 
    # ... еще конфигурация 
    # перенаправляем все запросы с http://www.example.com/sites/default/files/* на http://user.example.com/* при помощи установки header в 302
    location /sites/default/files {
        rewrite ^(/files/sites/default/files/)(.*)$ http://user.examle.com/$2 permanent;
    }
}

Теперь для http://user.example.com в nginx осталось настроить статическую отдачу файлов из директории с пользовательскими файлами:

server {
    listen user.example.com:80;
    server_name user.example.com;
    location / {
        root /var/www/vh/www.example.com/sites/default/files;
    }
}

Вроде теперь работает и все это можно сделать даже прямо на работающем сайте, браузеры правильно отработают перенаправление на user.example.com, но есть одна проблема: IMCE ничего не знает про перенаправление и у него всюду ссылки на www.example.com, а хочется чтобы пользователь получал ссылку на user.example.com
Для этого надо хакнуть модуль imce_file_path, который распространяется в составе набора модулей imce_tools.
Хак очень простой, надо на месте вывода ссылки правильно ее подменить. 
В файле /var/www/vh/www.example.com/sites/all/modules/imce_tools/modules/imce_file_path/imce_file_path.js заменяем 6 строку:
jQuery("#imce-file-path span").html(Drupal.t('File URL path: ') + imce.getURL(fid));
на 
jQuery("#imce-file-path span").html(Drupal.t('File URL path: ') + imce.getURL(fid).replace("www.example.com/sites/default/files","user.example.com"));

Профит!

Комментарии

Популярные сообщения из этого блога

Обзор почтового клиента Pronto Pro!

Подключаем ZFS over iSCSI на Oracle Linux 8 (CentOS) в Proxmox

Архитектура катастрофоустойчивого сервиса