2010-03-31 19 views
14

Ho attivato un'applicazione di esempio che utilizza Amazon S3 per l'hosting di immagini. Sono riuscito a convincerlo a lavorare. L'applicazione è ospitata allo github.com. L'applicazione consente di creare utenti con una foto del profilo. Quando carichi la foto, l'applicazione web la memorizza su Amazon S3 anziché sul tuo file system locale. (Molto importante se ospiti a heroku.com)Come rendere le immagini ospitate su Amazon S3 meno pubbliche ma non completamente private?

Tuttavia, quando ho fatto una "vista sorgente" nel browser della pagina ho notato che l'URL dell'immagine era un URL Amazon S3 nel bucket S3 che ho assegnato a l'applicazione. Ho tagliato & incollato l'URL ed è stato in grado di visualizzare l'immagine nello stesso browser e in un altro browser in cui non ho avuto sessioni aperte sulla mia app Web o su Amazon S3.

Esiste un modo per limitare l'accesso a tale URL (e immagine) in modo che sia accessibile solo ai browser registrati nelle mie applicazioni?

La maggior parte delle informazioni che ho trovato sugli ACL Amazon parlano solo dell'accesso solo per il proprietario o per gruppi di utenti autenticati con Amazon o AmazonS3 o per tutti in modo anonimo.

EDIT ---- UPDATE 7 luglio, 2010

Amazon ha just announced più modi per limitare l'accesso agli oggetti S3 e secchi. Tra gli altri modi, ora puoi limitare l'accesso a un oggetto S3 qualificando il referrer HTTP. Sembra interessante ... Non vedo l'ora di aggiornare i loro documenti di sviluppo.

risposta

3

S3 è un servizio separato e non conosce le sessioni.

La soluzione generica consiste nel riconoscere i vantaggi e le proprietà di sicurezza che assegnano a ciascuna risorsa una chiave separata, univoca, molto lunga e casuale, che fa parte dell'URL di quella risorsa. Se lo desideri, puoi anche assegnare una chiave con 512 bit di casualità effettivi e quell'URL rimarrà inutilizzato per un tempo molto lungo.

  • Perché qualcuno che al momento t ha accesso a un bene può semplicemente copiare l'asset per riferimento futuro, ha senso per consentire alla persona di conoscere l'URL e accedere al bene in qualsiasi momento.
  • Allo stesso modo, poiché tale persona può semplicemente scaricare l'asset e distribuirlo ad altri, ha senso consentire a tale persona di distribuire l'URL ad altri a cui altrimenti avrebbe semplicemente distribuito l'asset stesso.
  • Poiché tale accesso è di sola lettura e poiché le scritture sono limitate ai server del sito Web, non vi è alcun rischio di "hacking" dannoso da parte di chiunque abbia questo accesso.

È necessario determinare se questo è sufficiente sicurezza. Se non lo è, allora forse S3 non fa per te, e forse hai bisogno di memorizzare le tue immagini come colonne binarie nel tuo database e metterle in cache in memcached, cosa che puoi fare su Heroku.

+0

@Justice - Grazie per una risposta completa e ben motivata. È esattamente il ragionamento di cui avevo bisogno per usare S3. Le risorse memorizzate su S3 non sono super-critiche per quanto riguarda la privacy, e gli URL sono disponibili solo per gli utenti che hanno effettuato l'accesso. Suppongo di dover fare un qualche tipo di hash salato per generare il numero casuale. –

+1

+1 uno per i punti logici. Anche la generazione di un nuovo URL randomizzato per ogni aggiornamento alla risorsa è importante. –

1

Penso che il meglio che puoi fare sia ciò che fa drop.io. Sebbene i dati siano in linea di principio accessibili a chiunque, gli dai un URL ampio e casuale. Chiunque conosca l'URL può accedervi, ma la tua applicazione controlla chi può vedere l'URL.

Tipo di sicurezza attraverso l'oscurità.

Si può pensare ad esso come la password inclusa nell'URL. Ciò significa che se si prende sul serio la sicurezza, è necessario trattare l'URL come informazioni riservate. Devi assicurarti che questi link non trapelino anche ai motori di ricerca.

È inoltre complicato revocare i diritti di accesso. L'unica cosa che puoi fare è invalidare un URL e assegnarne uno nuovo.

9

Per i file dove la privacy in realtà le cose, gestiamo in questo modo:

  • I file vengono memorizzati con un ACL privata, il che significa che solo un agente autorizzato può scaricare (o caricare) li
  • Per accedere a un di file, ci colleghiamo a http://myapp.com/download/{s3-path}, dove download corrisponde a un controller (nel senso MVC)
  • ACL sono implementate come appropriato in modo che solo gli utenti registrati possono accedere tale controller/azione
  • che il download del controller t esegue il file utilizzando l'API, quindi lo invia all'utente con il tipo mime corretto, le intestazioni della cache, la dimensione del file, ecc.

Utilizzando questo metodo, si finisce per utilizzare molta più larghezza di banda del necessario, ma si salva ancora in memoria. Per noi questo funziona, perché tendiamo a esaurire lo spazio di archiviazione molto più rapidamente della larghezza di banda.

Per i file in cui la privacy è solo una questione, generiamo un hash casuale che usiamo per l'URL. Questo è fondamentalmente la sicurezza attraverso l'oscurità, e devi stare attento che il tuo hash è sufficientemente difficile da indovinare.

Tuttavia, quando ho fatto una "vista sorgente" nel browser della pagina ho notato che l'URL dell'immagine era un URL Amazon S3 nel bucket S3 che ho assegnato all'app. Ho tagliato & incollato l'URL ed è stato in grado di visualizzare l'immagine nello stesso browser e in un altro browser in cui non ho avuto sessioni aperte sulla mia app Web o su Amazon S3.

Ricordare che questo non è diverso da qualsiasi immagine memorizzata altrove nella root dei documenti. Potrebbe essere necessario o meno il tipo di sicurezza che stai cercando.

+0

Se * veramente * avete bisogno degli ACL, questo è sicuramente come farlo.Tuttavia, su Heroku, e in base ai modelli di accesso per queste risorse, questa strategia ti costringerà a "manovrare i tuoi dynos" molto più velocemente che in altri modi. – yfeldblum

+0

Giustizia: non sono sicuro che sia peggio di come sarebbe archiviare il file localmente e trasmetterlo in streaming attraverso l'applicazione, però. Se si desidera bloccare i file in modo non banale, lo streaming dell'applicazione è fondamentalmente l'unica soluzione. Certamente, poche applicazioni hanno quel tipo di requisito. Sono anche abituato a lavorare in un ambiente server dedicato, quindi forse il mio consiglio non è applicabile a heroku. – notJim

+0

Grazie per la risposta completa. –

5

Amazon's Ruby SDK (https://github.com/aws/aws-sdk-ruby) ha metodi utili che lo rendono un gioco da ragazzi per fare questo. "url_for" può generare un URL leggibile temporaneamente per un oggetto S3 altrimenti privato.

Ecco come creare un URL leggibile, che scade dopo 5 minuti:.

oggetto = AWS :: S3.new.buckets [ 'SECCHIELLO'] oggetti oggetto [ 'chiave']

.url_for (: leggere,: scade => 300) .to_s

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

+0

Hanno una funzionalità simile per gli URL firmati nell'SDK di PHP. http://docs.aws.amazon.com/aws-sdk-php/guide/latest/service-s3.html#creating-a-pre-signed-url Penso che questa sia la migliore soluzione attuale per questo poster tipo di problema – Chris

Problemi correlati