È un approccio abbastanza buono per proteggere un'API RESTful?

2

Voglio utilizzare l'autenticazione basata su token in cui l'utente effettua il login con una combinazione nome utente / password. Il server dovrebbe assicurarsi che il nome utente e la password corrispondano e quindi restituire un token che sarebbe utilizzato dal client per effettuare successive chiamate API. Questi token scadranno dopo un certo periodo di tempo (4 ore è quello che sto pensando), dopo di che l'utente dovrebbe accedere nuovamente.

Il modo in cui voglio generare token è questo: hash SHA256 di 3 stringhe generate casualmente (caratteri - [0-9, a-z, A-Z]), concatenati. Conserverei questo token in una tabella di database insieme al nome utente e al tempo di accesso.

Quando viene effettuata una richiesta API con questo token, sarei in grado di ottenere l'utente dal token.

Voglio proteggermi dagli attacchi di forza bruta.

Voglio implementare tutto questo in PHP. Questo approccio è abbastanza buono? Se no, perché? E quale sarebbe un modo migliore per farlo? Dovrebbe esserci un modo per ottenere l'utente solo dal token (senza cercare da un database)? Se sì, perché?

Sono un principiante per quanto riguarda la sicurezza, quindi le spiegazioni dettagliate sarebbero molto apprezzate.

    
posta Ayush 02.09.2016 - 17:46
fonte

2 risposte

2

The way I want to generate tokens is this : SHA256 hashes of 3 randomly generated strings (characters - [0-9,a-z,A-Z]), concatenated.

C'è nessun punto in dati casuali di hashing .

Evita l'uso delle funzioni predefinite rand om in quanto non sono sicure. Utilizza un PSRNG sicuro crittograficamente sicuro per generare i dati casuali. Ad esempio, su sistemi simil-UNIX è possibile leggere i dati su /dev/urandom . Prevedo che PHP abbia un modo documentato indipendente dalla piattaforma per creare dati casuali crittograficamente sicuri.

Il token dovrebbe avere 72 bit di entropia o più .

I would store this token in a database table along with the username and the login time.

Come forse saprai, dovresti non archiviare le password utente , ma utilizzare un Hash lento come bcrypt.

Allo stesso modo, per i token di sessione , non devi memorizzarli, ma usa un Hash veloce per questi. Quindi il tuo database dovrebbe memorizzare un hash SHA-256 del token. Evitare l'archiviazione del token originale è utile per alcuni schemi di gestione delle chiavi o attacchi caso limite (ad esempio SQLi limitato) che potresti avere lungo la strada.

When an API request is made with this token, I would be able to get the user from the token.

Sembra buono.

I want to implement all of this in PHP.

Questi concetti sono indipendenti dal linguaggio. : -)

Devi assolutamente accertarti di utilizzare HTTPS / TLS per crittografare la connessione e verificare l'identità del server prima di inviare qualsiasi dettaglio di autenticazione sensibile come password o token di sessione.

Ti consigliamo anche di verificare che l'indirizzo IP corrisponda a com'era quando l'utente ha effettuato l'accesso per la prima volta. Se l'indirizzo IP cambia durante la sessione, potrebbe essere un indizio del fatto che il token è stato rubato .

Sfortunatamente gli utenti di telefoni cellulari e gli utenti di determinati paesi stranieri hanno frequentemente cambiato gli indirizzi IP, quindi una tale restrizione non avrebbe funzionato per loro.

    
risposta data 02.09.2016 - 19:17
fonte
0

L'approccio "standard" a questo (a mio avviso, avendolo fatto di recente) consiste nell'utilizzare il flusso del proprietario delle risorse OAuth.

Ciò significa che fai esattamente ciò che suggerisci e crea un "access_token" che è ordinato, quindi opzionalmente, un "refresh_token" che è vissuto più a lungo e ti concede la possibilità di ottenere un nuovo access_token senza reinserire il tuo le credenziali.

Il token di accesso può, o non può, essere archiviato nel datastore dell'applicazione per scopi di revoca, tuttavia, non è un "puntatore" a qualcosa nel database. Conterrebbe tutte le informazioni necessarie per la richiesta. Quindi questo è identificativo dell'utente, ruoli, origini, ecc.

Generalmente, access_token viene inviato come intestazione di autorizzazione, che viene analizzata da una sorta di middleware e presentata al tuo codice come dati non elaborati.

Non sono sicuro delle tecnologie all'interno di PHP, ma i termini che dovresti cercare sono: OAuth 2.0 e token al portatore.

Il mio ultimo consiglio è: non farlo da solo, ci sono persone che passano la vita a farlo. È più probabile che ti renderai insicuro provando a farlo da solo.

    
risposta data 02.09.2016 - 19:00
fonte

Leggi altre domande sui tag