Безопасное хранение и обслуживание файлов для нескольких клиентов

8

Мы работаем над веб-приложением, в котором (помимо других функций) наши пользователи могут загружать свои файлы. Однако мы не можем хранить эти файлы на нашем VPS, поскольку пространство для хранения ограничено, поэтому мы решили использовать S3.

Основная проблема заключается в том, что мы должны обеспечить пользователям доступ только к своим данным. Поэтому мы храним список файлов в нашей базе данных и список пользователей, имеющих к ним доступ. Наш сервер может легко решить, имеет ли пользователь доступ к файлу или нет. Но как на самом деле обслуживать файлы пользователям?

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

1. Генерирование (истечение) подписанных URL с помощью PHP

Это действительно простой подход, он также быстрый, но приводит к очень и очень уродливым и длинным URL.

Вот как это сделать .

2. Запутанные URL

Это означает, что мы сохраняем файлы общественности для чтения на S3, но все файлы сохраняются в трудно угадать с именем папки , такие как: 24fa0b8ef0ebb6e99c64be8092d3ede20000. Однако, возможно, это не самый безопасный путь. Даже если вы никогда не сможете угадать имя папки, после того, как вы узнаете ее (потому что у вас есть доступ к ней), вы можете поделиться этой ссылкой с кем угодно (с любым не уполномоченным лицом).

3. Скачать файлы через наш сервер

Это означает, что файлы не обслуживаются непосредственно S3, но сначала наш сервер читает их безопасно и обслуживает. Мы действительно не хотим этого :)

4. Проверка реферера

Решение обфусцированных URL-адресов можно улучшить, «убедившись», что запрос поступил с нашего сервера (вы можете настроить S3 для проверки реферера). Однако это было бы очень ненадежным решением, потому что не все браузеры отправляют данные реферера, и они также могут быть поддельными.

Что такое хороший способ безопасного обслуживания файлов из Amazon S3 для разных клиентов?

Тамас Пап
источник
1
Почему вас волнует уродливый / длинный URL? Вы не заставляете пользователя печатать его?
ceejayoz
Я действительно считаю, что URL-адреса являются частью пользовательского опыта, и мы не хотим, чтобы они были слишком длинными и безобразными :)
Tamás Pap
2
Я бы сказал, что в этом случае безопасность и стабильность должны превосходить красивые URL. Это не постоянные ссылки на сообщения в блоге.
ceejayoz

Ответы:

12

Это действительно граничит с «Делай мою системную архитектуру» для тебя, но твои четыре идеи являются интересными примерами в области переменной безопасности, поэтому давайте попробуем твои варианты и посмотрим, как они поживают:


4. Проверка реферера

Реферер предоставляется клиентом. Доверие к предоставленным клиентом данным аутентификации / авторизации в значительной степени лишает безопасности (я могу просто утверждать, что был отправлен с того места, откуда вы ожидаете, что я приду).
Вердикт: идея TERRIBAD - тривиально обойти.


3. Скачать файлы через наш сервер

Неплохая идея, если вы готовы потратить пропускную способность, чтобы ваш сервер был надежным.
Исходя из того, что вы уже решили проблему безопасности для своего обычного сервера / приложения, это наиболее безопасный из представленных вариантов.
Вердикт: хорошее решение. Очень безопасный, но, возможно, неоптимальный, если пропускная способность является фактором.


2. Запутанные URL

Безопасность через неизвестность ? В самом деле? Нет,
я даже не буду анализировать это. Просто нет.
Вердикт: если № 4 был TERRIBAD, то это TERRIWORSE, потому что людям даже не нужно пытаться подделать заголовок реферера. Угадай строку и выиграй приз все данные!


1. Генерирование (истечение) подписанных URL с помощью PHP

Эта опция имеет довольно низкий коэффициент сосания.
Любой может щелкнуть URL-адрес и перехватить данные, что является защитой «нет-нет», но вы смягчаете это, заставляя ссылку истечь (пока срок действия ссылки достаточно короткий, окно уязвимости мало).
Истечение срока действия URL-адреса может доставить неудобства некоторым пользователям, которые хотят долго держаться за ссылку для скачивания, или которые не получают ссылку своевременно - это отстой, но это может стоить того ,
Вердикт : не так хорошо, как № 3, но если пропускная способность является серьезной проблемой, это, безусловно, лучше, чем № 4 или № 2.


Что бы я сделал?

Учитывая эти параметры, я бы пошел с № 3 - Пропустить файлы через ваш собственный сервер переднего плана и аутентифицировать, как обычно делает ваше приложение. Предполагая, что ваша нормальная безопасность довольно приличная, это лучший вариант с точки зрения безопасности.
Да, это означает больше использования полосы пропускания на вашем сервере и больше ресурсов, играющих посредника - но вы всегда можете просто взять чуть больше за это.

voretaq7
источник
Это действительно полезный анализ, и я очень благодарен за него. Еще одно большое преимущество # 3 заключается в том, что - поскольку URL-адрес файла никогда не меняется - мы можем активно использовать кэширование в браузере. Еще раз спасибо за ваше время.
Тамас Пап
@ TamasPap, который является преимуществом № 3, чтобы быть уверенным - насколько большое преимущество зависит от того, насколько настойчиво вы можете настроить кэширование (и как часто люди получают доступ к этим файлам с «новых» машин).
voretaq7
4

Используйте предварительно подписанные запросы Amazon S3, чтобы обслуживать объекты S3 непосредственно пользователям после выполнения любой пользовательской проверки, которую вы пожелаете. Этот метод создает ограниченный по времени URL-адрес, по которому вы можете перенаправлять пользователей.

Майкл Хэмптон
источник
0

Есть и другой способ.

Вы можете указать AWS CloudFront на своем S3 Bucket и использовать подписанные куки-файлы для безопасной доставки контента вашим конечным пользователям.

Конечные пользователи должны войти на ваш сервер, чтобы получить подписанные файлы cookie, которые затем будут отправлены в CDN при доступе к любому файлу.

prcoder
источник