2013-05-06 8 views
32

Devo predisporre un piano per sviluppare un'API RESTful (Python/Flask) che potrebbe essere utilizzata dalla nostra futura app Web (Angularjs) e app mobili (iOS/Android).API RESTful protetta che può essere utilizzata dall'app Web (angolare), iOS e Android

Ho svolto ricerche per tre giorni e ho riscontrato diversi scenari: L'utilizzo di HTTPS è uno dei metodi in alto per mantenerlo più sicuro. Ma https è più lento, il che potrebbe significare che abbiamo bisogno di server più veloci e costosi.

  1. Utilizzo di base-Http-Auth e invio nome utente/password in chiaro (ma https) sul filo per ogni richiesta all'API.
  2. Utilizzo di Digest-Auth, che è un hash della password e il rilevamento sarebbe automatico Questo funzionerebbe per l'app Web, tuttavia non è stato possibile confermare se iPhones e Android supportassero questo in modo nativo. Se lo fanno, quella potrebbe essere una soluzione facile!
  3. Utilizzo di un'intestazione http personalizzata, in cui vorrei inviare una stringa di autenticazione personalizzata nell'intestazione http su un'autenticazione corretta. Ma poi devo assicurarmi di inviare questo codice di autenticazione per ogni richiesta fatta dall'utente. Questo lo rende esattamente come 1) con la differenza che non vengono utilizzate password semplici e il codice di autenticazione può scadere senza alcun rischio. Anche problematico è il tracciamento del codice di autenticazione, che non è più automatico come in 2)
  4. L'utilizzo di OAuth è un'opzione. Ma è abbastanza difficile da configurare. Se non c'è modo migliore, forse è l'unico modo?
  5. Protezione dell'API come Amazon S3 come descritto in questo great article. In breve, dice che sia il server che il client avrebbero saputo di una chiave privata, che avrebbero usato per cancellare la comunicazione. Sarà come una stretta di mano da gangster, che ti fideresti solo del ragazzo delle consegne, se conosce la stretta di mano gangsta. Proseguendo lungo la commenti qualcuno chiede:

Come mantenere la chiave privata “sicuro” in un HTML5 App puro?

Hai esattamente ragione; in una pura app HTML5 (JS/CSS/HTML), non c'è protezione della chiave. Si farebbe tutte le comunicazioni su HTTPS, nel qual caso non sarebbe necessaria una chiave poiché si potrebbe tranquillamente identificare un client utilizzando un API_KEY standard o qualche altro identificatore amichevole senza la necessità o la complessità di un HMAC.

Quindi, in altre parole, non c'è nemmeno il senso di utilizzare il metodo per un'app Web in primo luogo. E onestamente non capisco come dovrebbe funzionare anche sul dispositivo mobile. Un utente scarica la nostra app e come posso inviare la chiave privata dall'iPhone al server? Nel momento in cui l'ho trasferito, sarà compromesso.

Più mi sto dedicando alla ricerca, più sto diventando indeciso.

Speravo di chiedere ad alcuni professionisti che l'hanno già fatto e di condividere la loro esperienza. Molte grazie

+2

Sto lottando con la stessa domanda. L'autenticazione sembra essere l'elefante nella sala REST ... – jbandi

+0

jbandi, questa domanda riguarda più la protezione del traffico piuttosto che l'autenticazione (se sto leggendo questo diritto). Se hai una domanda specifica su come gestire l'autenticazione nelle API RESTful/Web, non mi dispiacerebbe rispondergli. Una volta definite, le opzioni di autenticazione/gestione delle sessioni sono identiche alle tradizionali applicazioni web. –

risposta

65

Sembra che tu stia confondendo/fondendo insieme due concetti diversi. Iniziamo a parlare di crittografia del traffico (HTTPS) e quindi iniziamo a parlare di diversi modi per gestire sessioni autenticate. In un'applicazione sicura questi non sono compiti che si escludono a vicenda. Sembra anche che ci sia potenzialmente un fraintendimento su come la gestione delle sessioni possa influire sull'autenticazione. Sulla base di ciò, fornirò un primer sulla gestione delle applicazioni web/web api, l'autenticazione e la crittografia.

Introduzione

Session Management

transazioni HTTP sono apolidi per impostazione predefinita. HTTP non specifica alcun metodo per far sapere alla tua applicazione che una richiesta HTTP è stata inviata da un utente specifico (autenticato o meno).

Per applicazioni Web robuste, questo non è accettabile. Abbiamo bisogno di un modo per associare richieste e dati realizzati attraverso più richieste. Per fare ciò, su richiesta iniziale al server, a un utente deve essere assegnata una "sessione". Generalmente le sessioni hanno un qualche tipo di ID univoco che viene inviato al client. Il client invia quell'ID di sessione ad ogni richiesta e il server utilizza l'ID di sessione inviato in ogni richiesta per preparare correttamente una risposta per l'utente.

È importante ricordare che un 'id di sessione' può essere chiamato molte altre cose. Alcuni esempi sono: token di sessione, token, ecc. Per coerenza userò 'id di sessione' per il resto di questa risposta.

Ogni richiesta HTTP dal client deve includere l'id di sessione; questo può essere fatto in molti modi. Esempi popolari sono:

  1. Può essere memorizzato in un cookie - i cookie per il dominio corrente vengono inviati automaticamente ad ogni richiesta.
  2. Può essere inviato sull'URL - ogni richiesta potrebbe inviare l'ID di sessione sull'URL, non suggerito poiché gli ID di sessione rimarranno nella cronologia dei clienti
  3. Può essere inviato tramite intestazione HTTP - ogni richiesta dovrebbe essere necessaria per specificare l'intestazione

La maggior parte dei framework di applicazioni Web utilizza i cookie. Tuttavia, l'applicazione che si basa su JavaScript e design di pagine singole può scegliere di utilizzare un'intestazione HTTP/memorizzarla in un'altra posizione che è osservabile dal server.

È molto importante ricordare che la risposta HTTP che notifica il client del proprio ID di sessione e le richieste del client che contengono l'id di sessione sono completamente in chiaro e al 100% non sicure. Per combatterlo, tutto il traffico HTTP deve essere crittografato; è qui che entra in gioco HTTPS.

È anche importante sottolineare che non abbiamo parlato del collegamento di una sessione a un utente specifico nel nostro sistema. La gestione delle sessioni sta semplicemente associando i dati a un cliente specifico che accede al nostro sistema. Il client può essere in stati autenticati e non autenticati, ma in entrambi gli stati generalmente hanno una sessione.

autenticazione

autenticazione è dove ci colleghiamo una sessione di un utente specifico nel nostro sistema. Questo è generalmente gestito da un processo di accesso in cui un utente fornisce le credenziali, quelle credenziali sono verificate e quindi colleghiamo una sessione a un record utente specifico nel nostro sistema.

L'utente è a sua volta associato ai privilegi per il controllo di accesso a grana fine tramite elenchi di controllo di accesso e voci di controllo di accesso (ACL e ACE). Questo è generalmente indicato come "Autorizzazione". La maggior parte dei sistemi ha sempre Autenticazione e Autorizzazione. In alcuni sistemi semplici tutti gli utenti autenticati sono uguali, nel qual caso non si avrà un'autorizzazione oltre l'autenticazione semplice. Ulteriori informazioni su questo argomento sono fuori dallo scopo di questa domanda, ma si consideri la lettura di ACE/ACL.

Una sessione specifica può essere contrassegnata come rappresentante di un utente autenticato in diversi modi.

  1. I loro dati di sessione lato server memorizzati potrebbe memorizzare il proprio user ID/qualche altra bandiera che denota che l'uso è autenticato come utente specifico
  2. Un altro utente di token potrebbe essere inviare al client come un ID di sessione (quale sopra HTTP non crittografato è altrettanto pericoloso come l'invio di un id di sessione non criptato)

Entrambe le opzioni vanno bene. In genere si tratta della tecnologia in cui si sta lavorando e di ciò che offrono di default.

Un client avvia generalmente il processo di autenticazione. Questo può essere fatto inviando credenziali a un URL specifico (ad esempio, yoursite.com/api/login). Tuttavia, se vogliamo essere 'RESTful', in genere fare riferimento a una risorsa con un nome e fare l'azione di 'creare'. Questo potrebbe essere fatto richiedendo un POST delle credenziali a yoursite.com/api/authenticatedSession/. Dove l'idea sarebbe quella di creare una sessione autenticata. La maggior parte dei siti appone solo le credenziali a/api/login o simili. Questo è un allontanamento dagli ideali "veri" o "puri" RESTful, ma la maggior parte delle persone trova questo un concetto più semplice piuttosto che pensarlo come "creare una sessione autenticata".

crittografia

HTTPS viene utilizzata per crittografare il traffico HTTP tra un client e server. In un sistema che si basa su utenti autenticati e non autenticati, tutto il traffico che si basa su un utente che viene autenticato deve essere crittografato tramite HTTPS; Non c'è modo di aggirarlo.

La ragione di ciò è che se si autentica un utente, si condivide un segreto con loro (il proprio ID di sessione, ecc.) E quindi si inizia a sfilare quel segreto in un semplice HTTP, la loro sessione può essere dirottata da man-in-the- attacchi di mezzo. Un hacker aspetterà che il traffico passi attraverso una rete osservata e rubi il segreto (dal suo testo semplice su HTTP) e quindi avvenga una connessione al server fingendo di essere il client originale.

Il modo in cui le persone lo combattono associando l'indirizzo IP remoto delle richieste a una sessione autenticata. Questo è inefficace da solo in quanto qualsiasi hacker sarà in grado di falsificare le loro richieste di indirizzo IP remoto nelle loro false richieste e quindi osservare le risposte che il server sta inviando.Molti sostengono che non vale nemmeno la pena di implementare a meno che non si stiano monitorando i dati storici e li si utilizzi per identificare gli schemi di accesso di un utente specifico (come fa Google).

Se è necessario suddividere il sito tra le sezioni HTTP e HTTPS, è fondamentale che il traffico HTTP non invii o riceva l'ID di sessione o alcun token utilizzato per gestire lo stato di autenticazione di un utente. È anche importante non inviare dati sensibili delle applicazioni all'interno di richieste/risposte non HTTP.

L'unico modo per proteggere i dati all'interno di applicazioni Web/API è crittografare il traffico.

tuoi argomenti uno per uno

Basic-Http-Auth

  • Autenticazione: SI
  • Session Management: NO
  • Crittografia: No

Questo è un metodo per l'autenticazione solo tramite la risorsa Web. L'autenticazione di base autentica gli usi per risorsa identificata dall'URL. Questo è stato implementato più comunemente da Apache HTTP Web Server con l'uso dell'autenticazione di directory/posizione basata su .htaccess. Le credenziali devono essere inviate con ogni richiesta; i clienti generalmente lo gestivano in modo trasparente per gli utenti.

L'autenticazione di base può essere utilizzata da altri sistemi come modalità di autenticazione. Tuttavia, i sistemi che utilizzano Basic-Http-Auth forniscono l'autenticazione e la gestione delle sessioni, non la stessa Autenticazione Http di base.

  • Questa non è la gestione delle sessioni.
  • Questa non è crittografia; contenuto e credenziali sono quasi al 100% in testo semplice
  • Questo non protegge il contenuto della richiesta/risposta HTTP dell'applicazione.

Digest-Auth

  • Autenticazione: SI
  • Session Management: NO
  • Crittografia: NO

Questo è esattamente lo stesso di base-Http-Auth con l'aggiunta di alcuni semplici digestivi MD5. Questa digitazione non dovrebbe essere invocata invece di usare la crittografia.

  • Questa non è la gestione delle sessioni.
  • Questa non è crittografia; il digest si rompe facilmente
  • Questo non protegge il contenuto delle richieste/risposte HTTP dell'applicazione.

OAuth

  • Autenticazione: SI
  • Session Management: NO
  • Crittografia: NO

OAuth solo ti permette di avere un servizio esterno convalidare le credenziali. Dopodiché spetta a te gestire/lavorare con il risultato della richiesta di autenticazione al tuo provider OAuth.

  • Questa non è la gestione delle sessioni.
  • Questa non è crittografia; il traffico dei tuoi siti è ancora in chiaro. Il processo di autenticazione sarà sicuro a causa delle restrizioni HTTPS, ma la tua applicazione è ancora vulnerabile.
  • Questo non protegge il contenuto della richiesta/risposta HTTP dell'applicazione.

Gangster Handshake/un'intestazione HTTP personalizzata

  • Autenticazione: SI, potenzialmente
  • Session Management: SI, potenzialmente
  • Crittografia: NO

"Custom Intestazione HTTP "è un tipo di" Gangster Handshak es "; come tale userò la stessa sezione per discuterne. L'unica differenza è che una "intestazione HTTP personalizzata" sta specificando dove verranno salvati hanshake (ID di sessione, token, token di autenticazione dell'utente, ecc.) (Cioè in un'intestazione HTTP).

È importante notare che questi non specificano come verrà gestita l'autenticazione, né specificano in che modo verrà gestita la gestione della sessione. Descrivono essenzialmente come e dove verranno memorizzati gli ID di sessione/i token di autenticazione.

L'autenticazione dovrebbe essere gestita dall'applicazione o da una terza parte (ad esempio OAuth). La gestione delle sessioni dovrà ancora essere implementata. La cosa interessante è che puoi scegliere di unire i due se lo desideri.

  • Questa non è crittografia; il traffico dei tuoi siti è ancora in chiaro. Il processo di autenticazione sarà sicuro a causa delle restrizioni HTTPS se utilizzi OAuth, ma la tua applicazione è ancora vulnerabile.
  • Questo non protegge il contenuto della richiesta/risposta HTTP dell'applicazione.

Cosa dovete fare

...Consiglio vivamente di fare in modo che si capisce che una robusta applicazione web che è sicuro necessita il seguente:

  1. crittografia (HTTPS è praticamente l'unica scelta)
  2. Session Management
  3. autenticazione/autorizzazione

L'autorizzazione si basa sull'autenticazione. L'autenticazione si basa sulla gestione delle sessioni e la crittografia assicura che la sessione non venga dirottata e che le credenziali non vengano intercettate.

Flask Login

penso che si dovrebbe guardare in flask-login come un modo per evitare la ri-attuazione della ruota. Personalmente non l'ho mai usato (io uso la piramide per le applicazioni web in python). Tuttavia, l'ho già visto prima nelle applicazioni web/schede python. Gestisce sia l'autenticazione che la gestione delle sessioni. Getta l'API/applicazione web tramite HTTPS e disponi di tutti e tre (crittografia, gestione sessione e autenticazione utente).

Se non si può/non si può usare flask-login, prepararsi a scrivere il proprio, ma fare prima una ricerca su come creare meccanismi di autenticazione sicuri.

Se possibile, se non si capisce come scrivere una procedura di autenticazione si prega di non tentare senza prima imparare come gli hacker utilizzano attacchi basati modello, attacchi di temporizzazione, ecc

Si prega di cifrare il traffico

... oltrepassare l'idea che è possibile evitare l'uso di HTTPS con un uso "intelligente" del token. Sposta l'idea che dovresti evitare di utilizzare la crittografia HTTPS perché "è lento", intensivo del processo, ecc. È un processo intensivo perché è un algoritmo di crittografia. La necessità di garantire la sicurezza dei dati dell'utente e dei dati delle applicazioni dovrebbe sempre essere la massima priorità. Non vuoi passare attraverso l'orrore di notificare agli utenti che i loro dati sono stati compromessi.

+4

Ottima risposta per una tipica app web. Ma credo che OP stia chiedendo le opzioni per l'autenticazione per un server API REST. La gestione della sessione non è richiesta, ad esempio se la tua API REST utilizza Auth di autenticazione/digest di base HTTP. – jemeshsu

+0

@jemeshsu sono la stessa cosa. C'è poca differenza tra la creazione di un'API REST e un'applicazione web tradizionale in termini di gestione delle sessioni, autenticazione/autorizzazione e crittografia della trasmissione. –

1

L'https è più lento, ma non è un no. Solo l'handshake è più lento. Per noi il problema più grande è mantenere la coppia di chiavi sul lato server-mobile e sui diritti. Abbiamo implementato anche un digest di messaggi. Il problema è: è difficile impostare correttamente la versione di php-android-ios.Dopo averlo fatto (un parametro deve cambiare ciò che sta suggerendo a Google in un primo momento solo i risultati su Android) il problema sarà con i dispositivi di fascia bassa: a molto uso della CPU, lento nel processo di decrypt-encrypt, molto più lento di https, soprattutto quando è necessario trasformare 10kb String (può richiedere diversi minuti).

Se non trasferire i dati Nasa ad Hamas, che vorrei andare con un semplice crittografia over HTTP semplice: come invertire i bit o giù di lì ...

1

Go con HTTPS. È (marginalmente) più lento, ma la sicurezza che si ottiene da esso per il tempo di investimento relativamente breve (acquistando il certificato SSL e cambiando semplicemente i propri URL da http a https) vale la pena. Senza HTTPS, si corre il rischio che le sessioni degli utenti vengano dirottate su reti pubbliche non protette, che è estremamente easy for someone to do.

Problemi correlati