2016-06-26 75 views
25

Ho letto sulla messa in sicurezza delle API REST e ho letto su oAuth e JWT. Entrambi sono approcci davvero fantastici, ma da quello che ho capito, entrambi funzionano dopo che un utente è stato autenticato o in altre parole "connesso". Questo si basa sulle credenziali dell'utente oAuth e JWT sono generate e una volta ottenuto il token oAuth o JWT l'utente può eseguire tutte le azioni per le quali è autorizzato.Protezione dell'API REST non autenticata

Ma la mia domanda è, che dire dell'account di accesso e dell'iscrizione? Come li si protegge? Se qualcuno legge i miei file javascript per vedere le mie chiamate ajax, può facilmente scoprire i punti finali ei parametri passati, e potrebbero colpirli più volte attraverso alcuni client REST, più severamente potrebbero codificare un programma che colpisce la mia API di registrazione diciamo mille volte, che creerebbe un migliaio di utenti di spam, o potrebbero addirittura forzare l'API di login. Quindi come li si protegge?

Sto scrivendo la mia API in yii2.

+0

Qualcuno può leggere gli endpoint API dal JavaScript, anche se la minimizzazione dei tuoi file JS? –

+2

Minifying non risolve i problemi. È possibile copiare facilmente incollare l'intero codice in un IDE e il codice di formattazione automatica formatterà tutto il codice. –

+0

Ok, che dire dell'autenticazione basata su filtro convenzionale che può essere attivata subito dopo la richiesta. –

risposta

7

I tuoi URL saranno facilmente determinati. Dovresti avere una lista nera di indirizzi IP e quando un indirizzo IP agisce in modo sospetto, basta aggiungerlo alla lista nera. È possibile definire che cosa sospetto è, ma se non si è sicuri, si può iniziare con le seguenti:

Creare qualcosa come una tabella del database con questo schema:

ip_addresses (IP, is_suspicious, login_attempts, register_attempts)

Dove is_suspicious significa che è nella lista nera. login_attemtps e register_attempts dovrebbero essere valori json, mostrando la cronologia di quell'indirizzo IP che prova ad accedere/registrare. Se gli ultimi 20 tentativi non hanno avuto esito positivo ed erano entro un minuto, l'indirizzo IP dovrebbe essere inserito nella lista nera. Gli indirizzi IP in blacklist dovrebbero ricevere una risposta in cui sono inseriti nella blacklist qualunque sia la loro richiesta. Quindi, se negano i tuoi servizi o tentano di hackerare le cose, allora neghi i tuoi servizi da loro.

Password sicure che utilizzano sha1, ad esempio. Questo algoritmo è abbastanza sicuro ed è più veloce di sha256, ad esempio, che potrebbe essere eccessivo. Se la tua API coinvolge conti bancari o qualcosa di estremamente importante come questo, è abbastanza importante per i malintenzionati usare i server park per hackerarlo, quindi costringere gli utenti a creare password molto lunghe, inclusi numeri, caratteri speciali, lettere grandi e piccole.

+1

Questo è un ottimo suggerimento e funzionerà perfettamente per il login e la registrazione. Penso che se in qualche modo verranno effettuati 5 tentativi di registrazione entro gli ultimi 2 minuti, farò una lista nera. Allo stesso modo, se 10 tentativi di accesso e tutti gli errori vengono eseguiti in 2 minuti, anch'io li elenco in nero. Ma @Lajos cosa possiamo fare se l'hacker attacca usando server proxy? Avete qualche suggerimento per questo? –

+0

@EricB., I server proxy hanno indirizzi IP. È possibile aggiungere inizialmente una grande serie di server proxy e ogni volta che si verifica una situazione sospetta, è possibile controllare gli indirizzi IP da cui proviene la richiesta. Inoltre, c'è un modo per eliminare automaticamente alcuni server proxy, vedere questo: http://stackoverflow.com/questions/690025/how-to-tell-if-a-request-is-coming-from-a-proxy –

+0

Grazie per questo suggerimento @Lajos. Ha aiutato molto. Lo proverò sicuramente. Inoltre, accetterò la tua risposta se non ci sono risposte migliori. –

10

Il framework Yii 2.0 dispone di un filtro incorporato denominato yii\filters\RateLimiter che implementa un algoritmo di limitazione della velocità basato sullo leaky bucket algorithm. Ti permetterà di limitare il numero massimo di richieste accettate in un certo intervallo di tempo. Ad esempio, è possibile limitare entrambi gli endpoint di accesso e registrazione per accettare al massimo 100 chiamate API entro un intervallo di 10 minuti. Quando viene superato tale limite, viene generata un'eccezione yii\web\TooManyRequestsHttpException (codice di stato).

È possibile leggere ulteriori informazioni sull'API RESTful Yii2 related documentation o all'interno di questo SO post.

non ho usato io stesso finora, ma da quello che ho letto su di esso in documenti ufficiali, e voglio dire questo:

Nota che RateLimiter richiede $user per attuare il yii\filters\RateLimitInterface. RateLimiter non farà nulla se $user non è impostato o non implementa yii\filters\RateLimitInterface.

Suppongo che sia stato progettato per funzionare solo con gli utenti registrati, magari utilizzando la tabella del database relativa all'utente, quella predefinita introdotta nel modello avanzato. Non ne sono sicuro, ma so che è necessario archiviare il numero di richieste consentite e il timestamp correlato a una memoria persistente all'interno del metodo saveAllowance che sarà necessario definire nella classe utente. Quindi penso che dovrai monitorare gli utenti guest per gli indirizzi IP come suggerito da @LajosArpad, quindi forse ridisegnare la tua classe utente per mantenere le loro identità in modo da poterla abilitare.

Una ricerca google veloce mi consente di questa estensione: yii2-ip-ratelimiter a cui si può anche dare un'occhiata.

+0

ho scoperto il 'RateLimiter' e come hai fatto notare che richiede un Utente e sulla base applica i limiti. Più oltre il RateLimiter è per l'app in generale, non solo per alcuni apis credo. Quindi, una soluzione migliore che mi è venuta in mente è creare 2 app Yii supportate dallo stesso database. Uno è solo per questi servizi non protetti, che accedono alla tabella utente che non contiene la password del nome utente, invece contiene IP, analogamente un'altra app Yii che contiene il mio normale utente di logica applicativa. –

+0

Suggerirei 2 moduli. 'api' e' auth' each ** con la propria classe utente ** come l'ho fatto qualche tempo fa in questo [esempio] (https://github.com/tunecino/Yii2_foundation-apps/tree/master/ backend). il primo distribuisce le risorse mentre 'auth' distribuisce token e ha due controller: il primo contiene azioni che non richiedono l'autenticazione mentre il secondo le richiede come il logout o l'azione di revoca (si veda [qui] (https://github.com/tunecino/ Yii2_foundation-apps/tree/master/backend/auth/controller)) –

+0

su RateLimiter è un comportamento che puoi collegare a qualsiasi controller di cui hai bisogno dopotutto e puoi cambiare il modo in cui funziona come ho spiegato. nella mia app dimostrativa come esempio (che terminerò un giorno) la collegherei solo all'accountcontroller e rintraccerei gli utenti tramite IP probabilmente in un REDIS DB per prestazioni migliori. ma è così che lo vedo per la mia app che sto condividendo, forse per aiutare a ottenere idee per capire quali dolci migliori app. –

2

Per javascript è necessario utilizzare il flusso di Grant implicito OAuth 2.0 come Google o Facebook.
Accesso e registrazione utilizzano 2 pagina Web di base. Non dimenticare di aggiungere il captcha per loro.

Per alcuni client speciali come l'app mobile o il webserver:
Se si è sicuri che il file binario sia sicuro, è possibile creare un'API di accesso personalizzata per esso. In questa API devi provare a verificare il tuo cliente.

Una soluzione semplice, si può fare riferimento:

  • uso di un algoritmo di crittografia quali AES o 3DES per crittografare la password dal client utilizzare una chiave segreta (solo client e server sa su di esso)
  • utilizzare un algoritmo di hash come sha256 to hash (nome utente + ora del client + un'altra chiave privata ). Il client invierà l'ora del client e la stringa hash al server . Il server rifiuterà la richiesta se il tempo del client è troppo diverso dal server o la stringa hash non è corretta.

Esempio:

api/login?user=user1&password=AES('password',$secret_key1)&time=1449570208&hash=sha256('user1'+'|'+'1449570208'+'|'+$secret_key2) 

Nota: In ogni caso, il server dovrebbe usare captcha per evitare attacco di forza bruta, non credono in qualsiasi altro filtro

Chi captcha per REST API, possiamo crea una base captcha sul token.
Es.

Per firmare l'azione: è necessario chiamare 2 api

  1. /getSignupToken: per ottenere rispettivamente immagine url captcha e un'iscrizione Token .
  2. /iscrizione: per inviare iscrizione dei dati (comprendono iscrizione token e captcha digitato dall'utente)

Per l'azione login: possiamo richiedere captcha dal conte fallito base di dati di accesso sul nome utente

+0

I captcha funzionano quando si riempiono i moduli. Non funzionano quando si ha accesso diretto agli endpoint API. L'approccio client time può anche fallire sapendo che, apk app Android può essere facilmente convertito in codice java e si può facilmente scoprire la chiave dal codice e sapere che la logica per creare hash è aggiungere un tempo, e inviare lo stesso tempo in il servizio. Una volta che qualcuno ha conosciuto questa logica, il burte forcing è un gioco da ragazzi. –

+0

@EricB. OAuth 2.0 usa la pagina di login e la pagina di registrazione sono 2 normali moduli html, sono stati aperti sul browser, captchar in base alla sessione utente. Informazioni su Captcha per le API REST, possiamo creare captcha base su token. –

+0

Ovviamente qualcuno può decodificare il file APK, la soluzione di Encript è solo per restrizione. –

2

Folow mia api modulo qui per riferimento. Gestisco l'autenticazione dell'utente tramite il token di accesso. Al momento dell'accesso, genera token, quindi accedo nuovamente, il client deve inviare token e il server controllerà.

Yii2 Starter Kit lite