2010-03-31 2 views
14

Я запустил образец приложения, которое использует Amazon S3 для размещения изображений. Мне удалось уговорить его работать. Приложение размещено по адресу github.com. Приложение позволяет создавать пользователей с фотографией профиля. Когда вы загружаете фотографию, веб-приложение хранит ее на Amazon S3 вместо локальной файловой системы. (Очень важно, если вы размещаете по адресу heroku.com)Как сделать изображения размещены на Amazon S3 менее публичными, но не полностью частными?

Однако, когда я сделал «источник просмотра» в браузере страницы, я заметил, что URL-адрес изображения был URL-адресом Amazon S3 в ведро S3, которое я присвоил приложение. Я вырезал &, вставил URL-адрес и смог просмотреть изображение в том же браузере и в другом браузере, в котором у меня не было открытых сеансов для моего веб-приложения или Amazon S3.

Есть ли способ ограничить доступ к этому URL (и изображению), чтобы он был доступен только для браузеров, которые вошли в мои приложения?

Большая часть информации, которую я нашел о ACL Amazon, говорит только о доступе только для владельцев или групп пользователей, прошедших аутентификацию с помощью Amazon или AmazonS3, или для всех анонимно.

EDIT ---- UPDATE 7 июля 2010

Amazon имеет более just announced способы ограничения доступа к объектам S3 и ведрами. Среди других способов теперь вы можете ограничить доступ к объекту S3, присвоив HTTP-рефереру. Это выглядит интересно ... Я не могу дождаться, пока они обновят свои документы разработчика.

ответ

3

S3 - отдельная услуга и не знает о ваших сеансах.

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

  • Потому что кто-то во время t имеет доступ к активу может просто скопировать актив в будущее, это имеет смысл, чтобы позволить этому человеку знать URL и получить доступ к активу в любое время.
  • Аналогичным образом, поскольку этот человек может просто загрузить актив и распространять его другим, имеет смысл разрешить этому человеку распространять URL-адрес другим лицам, которым он иначе просто распределил бы этот актив.
  • Поскольку весь такой доступ доступен только для чтения, а так как записи ограничены серверами веб-сайта, нет никакого риска злонамеренного «взлома» от любого, у кого есть этот доступ.

Вы должны определить, достаточно ли этого. Если это не так, то, возможно, S3 не для вас, и, возможно, вам нужно сохранить ваши изображения в виде двоичных столбцов в своей базе данных и кэшировать их в memcached, что вы можете сделать на Heroku.

+0

@Justice - Спасибо за полный и очень аргументированный ответ. Это именно то, что мне нужно для использования S3. Активы, хранящиеся на S3, не являются сверхкритичными в отношении конфиденциальности, а URL-адреса доступны только для зарегистрированных пользователей. Полагаю, мне нужно сделать какой-то соленый хеш для генерации случайного числа. –

+1

+1 для логических точек. Важное значение имеет также создание нового рандомизированного URL-адреса для каждого обновления ресурса. –

1

Я думаю, что лучшее, что вы можете сделать, это то, что drop.io делает. Хотя данные в принципе доступны для всех, вы даете им большой и случайный URL-адрес. Любой, кто знает URL, может получить к нему доступ, но ваше приложение контролирует, кто видит URL.

Вид безопасности через безвестность.

Вы можете думать об этом как о пароле, включенном в URL-адрес. Это означает, что если вы серьезно относитесь к безопасности, вы должны рассматривать URL как конфиденциальную информацию. Вы должны убедиться, что эти ссылки не просачиваются в поисковые системы.

Также сложно отменить права доступа. Единственное, что вы можете сделать, это недействительность URL-адреса и назначение нового.

9

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

  • Файлы сохраняются с частным ACL, а это означает, что только уполномоченный агент может загрузить (или загрузить) их
  • Для доступа к файл, мы ссылаемся на http://myapp.com/download/{s3-path}, где download соответствует контроллеру (в смысле MVC)
  • списки ACL реализуются в зависимости от обстоятельств, так что только зарегистрированные пользователи могут получить доступ к этому контроллер/действие
  • , который загружает контроллер т он обрабатывает API, затем передает его пользователю с правильными типами mime-типа, заголовками кеша, размером файла и т. д.

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

Для файлов, в которых конфиденциальность касается только вопросов, мы генерируем случайный хеш, который мы используем для URL. Это в основном безопасность через неясность, и вы должны быть осторожны, что ваш хэш достаточно сложно угадать.

Однако, когда я сделал «источник просмотра» в браузере страницы, я заметил, что URL-адрес изображения был URL-адресом Amazon S3 в ведро S3, которое я назначил приложению. Я вырезал &, вставил URL-адрес и смог просмотреть изображение в том же браузере и в другом браузере, в котором у меня не было открытых сеансов для моего веб-приложения или Amazon S3.

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

+0

Если вы действительно нужны ACL, это определенно, как это сделать.Однако на Heroku и в зависимости от шаблонов доступа для этих активов эта стратегия заставит вас «кривовать ваши динозавры» намного быстрее, чем в противном случае. – yfeldblum

+0

Правосудие: Я не уверен, что это хуже, чем было бы хранить файл локально и передавать его через ваше приложение. Если вы хотите заблокировать файлы любым нетривиальным способом, потоковое использование приложения в основном является единственным решением. Конечно, у немногих приложений есть такое требование. Я также привык работать в выделенной серверной среде, поэтому, возможно, мой совет не применим к героку. – notJim

+0

Спасибо за очень полный ответ. –

5

В Ruby SDK от Amazon (https://github.com/aws/aws-sdk-ruby) есть полезные методы, позволяющие сделать это. «url_for» может генерировать временный читаемый URL-адрес для другого частного объекта S3.

Вот как создать читаемый URL, который истекает через 5 минут:.

объекта = AWS :: S3.new.buckets [ 'ВЕДРО'] объектов [ 'КЛЮЧ']

объект .url_for (: чтение,: истекает => 300) .to_s

AWS документации: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/S3Object.html#url_for-instance_method

+0

У них есть аналогичная функция для подписанных URL-адресов в PHP SDK. http://docs.aws.amazon.com/aws-sdk-php/guide/latest/service-s3.html#creating-a-pre-signed-url Я думаю, что это лучшее текущее решение для этого плаката вид проблемы. – Chris