2010-03-31 30 views
14

J'ai démarré un exemple d'application utilisant Amazon S3 pour l'hébergement d'images. J'ai réussi à l'amener à travailler. L'application est hébergée au github.com. L'application vous permet de créer des utilisateurs avec une photo de profil. Lorsque vous téléchargez la photo, l'application Web la stocke sur Amazon S3 au lieu de votre système de fichiers local. (Très important si vous hébergez à heroku.com)Comment rendre les images hébergées sur Amazon S3 moins publiques mais pas complètement privées?

Cependant, quand j'ai fait une "vue source" dans le navigateur de la page, j'ai remarqué que l'URL de l'image était une URL Amazon S3 dans le compartiment S3 que j'avais assigné l'application. J'ai coupé & collé l'URL et a été en mesure d'afficher l'image dans le même navigateur, et dans un autre navigateur dans lequel je n'avais pas de sessions ouvertes à mon application Web ou à Amazon S3.

Y a-t-il un moyen de restreindre l'accès à cette URL (et à cette image) afin qu'elle ne soit accessible qu'aux navigateurs connectés à mes applications?

La plupart des informations que j'ai trouvées sur les ACL Amazon ne traitent que de l'accès uniquement pour le propriétaire ou pour des groupes d'utilisateurs authentifiés avec Amazon ou AmazonS3, ou pour tout le monde de manière anonyme.

EDIT ---- Juillet à jour 7, 2010

Amazon a just announced plus des moyens pour limiter l'accès aux objets S3 et des seaux. Vous pouvez, entre autres, restreindre l'accès à un objet S3 en qualifiant le référent HTTP. Cela semble intéressant ... Je ne peux pas attendre jusqu'à ce qu'ils mettent à jour leurs documents de développement.

Répondre

3

S3 est un service distinct et ne connaît pas vos sessions.

La solution générique consiste à reconnaître les avantages et les propriétés de sécurité qui attribuent à chaque actif une clé distincte, unique, très longue et aléatoire, qui fait partie de l'URL de cet actif. Si vous le souhaitez, vous pouvez même attribuer une clé avec 512 bits aléatoires effectifs, et cette URL restera inaccessible pendant très longtemps.

  • Parce que quelqu'un qui, à temps t a accès à un actif peut simplement copier l'actif pour référence future, il est logique de permettre à cette personne de connaître l'URL et accéder à l'actif à tout moment. De même, comme cette personne peut simplement télécharger l'élément et le distribuer à d'autres, il est logique de permettre à cette personne de distribuer l'URL à d'autres personnes auxquelles il aurait simplement simplement distribué l'élément lui-même.
  • Étant donné que tous ces accès sont en lecture seule et que les écritures sont limitées aux serveurs de sites Web, il n'y a aucun risque de piratage malveillant de la part de toute personne disposant de cet accès.

Vous devez déterminer si la sécurité est suffisante. Si ce n'est pas le cas, alors S3 n'est peut-être pas pour vous, et peut-être avez-vous besoin de stocker vos images en colonnes binaires dans votre base de données et de les mettre en mémoire cache dans memcached, ce que vous pouvez faire sur Heroku.

+0

@Justice - Merci pour une réponse complète et très bien raisonnée. C'est exactement le raisonnement dont j'avais besoin pour utiliser S3. Les actifs stockés sur S3 ne sont pas super critiques en ce qui concerne la confidentialité, et les URL ne sont disponibles que pour les utilisateurs connectés. Je suppose que je dois faire une sorte de hash salé pour générer le nombre aléatoire. –

+1

+1 pour les points logiques. Générer une nouvelle URL aléatoire pour chaque mise à jour de la ressource est également important. –

1

Je pense que le mieux que vous pouvez faire est ce que fait drop.io. Alors que les données sont en principe accessibles à tous, vous lui donnez une URL volumineuse et aléatoire. Toute personne connaissant l'URL peut y accéder, mais votre application contrôle qui peut voir l'URL.

Sorte de sécurité à travers l'obscurité.

Vous pouvez considérer cela comme le mot de passe inclus dans l'URL. Cela signifie que si vous êtes sérieux au sujet de la sécurité, vous devez traiter l'URL comme une information confidentielle. Vous devez également vous assurer que ces liens ne fuient pas vers les moteurs de recherche.

Il est également difficile de révoquer les droits d'accès. La seule chose que vous pouvez faire est d'invalider une URL et d'en attribuer une nouvelle.

9

Pour les dossiers où la vie privée des questions en fait, nous traitons cela comme suit:

  • Les fichiers sont stockés avec une ACL privée, ce qui signifie que seul un agent autorisé peut télécharger (ou télécharger) les
  • Pour accéder à un fichier, nous associons à http://myapp.com/download/{s3-path}, où download correspond à un contrôleur (au sens MVC)
  • ACLs sont mises en œuvre selon le cas afin que seuls les utilisateurs connecté peut accéder à ce contrôleur/action
  • ce contrôleur téléchargements t Il utilise l'API, puis la transmet à l'utilisateur avec le bon type mime, les en-têtes de cache, la taille de fichier, etc.

En utilisant cette méthode, vous utilisez beaucoup plus de bande passante que nécessaire, mais vous économisez encore sur le stockage. Pour nous cela fonctionne, parce que nous avons tendance à manquer de stockage beaucoup plus rapidement que la bande passante.

Pour les fichiers où la confidentialité est uniquement une question importante, nous générons un hachage aléatoire que nous utilisons pour l'URL. C'est fondamentalement la sécurité à travers l'obscurité, et vous devez faire attention que votre hash est suffisamment difficile à deviner. Cependant, quand j'ai fait une "vue source" dans le navigateur de la page, j'ai remarqué que l'URL de l'image était une URL Amazon S3 dans le compartiment S3 que j'avais assigné à l'application. J'ai coupé & collé l'URL et a été en mesure d'afficher l'image dans le même navigateur, et dans un autre navigateur dans lequel je n'avais pas de sessions ouvertes à mon application Web ou à Amazon S3. Gardez à l'esprit que ce n'est pas différent de n'importe quelle image stockée ailleurs dans la racine de votre document. Vous pouvez ou ne pas avoir besoin du type de sécurité que vous recherchez.

+0

Si vous avez vraiment besoin des listes de contrôle d'accès, c'est définitivement ce qu'il faut faire.Cependant, sur Heroku, et en fonction des patrons d'accès pour ces ressources, cette stratégie vous forcera à "lancer vos dynos" beaucoup plus rapidement qu'autrement. – yfeldblum

+0

Justice: Je ne suis pas sûr que ce soit pire que ce serait de stocker le fichier localement et le diffuser via votre application, cependant. Si vous souhaitez verrouiller les fichiers de manière non triviale, la diffusion en continu dans l'application est la seule solution. Bien sûr, peu d'applications ont ce genre d'exigence. Je suis également habitué à travailler dans un environnement de serveur dédié, alors peut-être que mon conseil ne s'applique pas à heroku. – notJim

+0

Merci pour votre réponse très complète. –

5

Ruby SDK d'Amazon (https://github.com/aws/aws-sdk-ruby) a des méthodes utiles qui font un clin d'oeil pour faire cela. "url_for" peut générer une URL lisible temporaire pour un objet S3 autrement privé.

Voici comment créer une URL lisible qui expire au bout de 5 minutes.

objet = AWS :: S3.new.buckets [ 'bucket'] objets [ 'KEY']

objet .url_for (: lire: expires => 300) .to_s

documentation AWS: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/S3Object.html#url_for-instance_method

+0

Ils ont une fonctionnalité similaire pour les URL signées dans le SDK PHP. http://docs.aws.amazon.com/aws-sdk-php/guide/latest/service-s3.html#creating-a-pre-signed-url Je pense que c'est la meilleure solution actuelle pour cette affiche genre de problème. – Chris