Come posso proteggere la mia API REST?

80

In dettaglio, ecco il problema:

Sto costruendo un'app per Android, che consuma la mia API REST sul back-end. Ho bisogno di creare un'API di registrazione e accesso per iniziare. Dopo aver cercato con Google per un po ', mi sembra che ci siano solo due approcci che posso adottare.

  • Durante la registrazione, utilizzo link e ottengo le credenziali dell'utente; salvarlo nel mio DB contro il nome utente (lato server). Durante l'accesso, utilizzo ancora link e chiedo le credenziali dell'utente; verificare la password hash sul DB e restituirgli un ID di sessione, che sto pianificando di non scadere mai a meno che non esca. Inoltre, qualsiasi altra chiamata API (GET / POST) che l'utente effettua, sarà accompagnata da questo ID di sessione in modo da poter verificare l'utente.

Ma nell'approccio sopra sono obbligato a utilizzare link per qualsiasi chiamata API, altrimenti sono vulnerabile a Man in the Middle Attack , ovvero se qualcuno annusa il mio ID di sessione, può ricostruire simili richieste GET / POST che non vorrei. Ho ragione con l'assunto sopra?

  • La seconda opzione è seguire il percorso di Amazon Web Services , dove uso l'autenticazione della chiave pubblica / privata. Quando un utente si registra, utilizzo l'API link per salvare le sue credenziali nel DB. Da quel momento in poi userò la password hash dell'utente come chiave privata. Qualsiasi ulteriore chiamata API che l'utente farà avrà un blob hash dell'URL della richiesta utilizzando la chiave privata dell'utente. Sul lato server ricostruisco l'hash utilizzando la chiave privata salvata. Se l'hash è una corrispondenza, lascio che l'utente faccia il suo compito, altrimenti rifiuta. In questa opzione ho bisogno di usare link solo per l'API di registrazione. Il REST può continuare su link .

Ma qui lo svantaggio è che sono costretto ad ospitare la mia API di registrazione in una directory virtuale separata (sto usando IIS e non sono sicuro di poter ospitare entrambe le API http e https nella stessa directory virtuale ). Quindi sono costretto a sviluppare l'API di registrazione in un file di progetto separato. Di nuovo, ho ragione con l'ipotesi precedente?

Modifica: sto utilizzando ASP.NET MVC4 per creare l'API Web.

Il motivo per cui sono riluttante a utilizzare link per tutte le mie chiamate API REST è che ritengo che non sia leggero e crei più payload della rete, il che potrebbe non essere più adatto per un'app mobile. Ulteriore crittografia / decodifica e ulteriore stretta di mano richiesta possono ulteriormente incidere sulla durata della batteria del cellulare? O non è significativo?

Quale dei due precedenti suggerimenti suggeriresti?

PS: siamo andati con Https ovunque, ed è stata la decisione migliore. Maggiori informazioni sul mio blog .

    
posta noob Mama 09.09.2012 - 10:01
fonte

6 risposte

50

Andrei con SSL / TLS ovunque (dato che controlli entrambi i lati, forzare TLS 1.2 dovrebbe essere fattibile). È relativamente semplice da utilizzare e offre molte funzionalità di sicurezza gratuite. Ad esempio, se non si utilizza SSL, è necessario preoccuparsi degli attacchi di riproduzione.

Se sei preoccupato per le prestazioni, assicurati che la ripresa della sessione sia supportata sia dal server che dal client. In questo modo le strette di mano successive molto più economiche. Poiché la stretta di mano è piuttosto costosa in SSL rispetto alla crittografia dei dati effettivi, ciò riduce considerevolmente il carico complessivo.

Se utilizzi HTTP 2, puoi persino inviare più richieste su una singola connessione, evitando in tal modo l'overhead completo di TCP e SSL sulle richieste successive.

    
risposta data 09.09.2012 - 12:25
fonte
23

Raccomando di utilizzare OAuth. Dovresti assolutamente leggerlo se non ti è familiare. Come plus, puoi utilizzare i provider di identità di terze parti, in modo che gli utenti possano utilizzare i loro account Google / Windows Live / ecc. Per la tua applicazione, risparmiando la registrazione.

Anche se si desidera eseguire il rollover del proprio framework di autenticazione, non è consigliabile utilizzare sessioni senza scadenza. La sessione dovrebbe scadere dopo un sufficiente periodo di inattività, altrimenti questo offre più spazio per lo sfruttamento (session-hijacking ad es.).

    
risposta data 09.09.2012 - 10:38
fonte
3

Dipende solo dalla sicurezza che ha bisogno di essere. Ogni volta che rendi la soluzione più complessa, probabilmente lascerai un buco aperto . Senza offesa intesa qui, ma suppongo che tu non sia un esperto di sicurezza, in base al fatto che stai facendo la domanda. È meglio utilizzare un qualche tipo di modulo standard di autenticazione e autenticazione.

Probabilmente starai bene, finché lo sarai:

  • crittografia della password (con qualcosa come AES o Blowfish)
  • salting the password
  • invio dei dati su HTTPS

Un'alternativa è OAuth.

Se qualcuno ti vuole hackerare abbastanza, troverà sempre un modo. Il segreto sta aumentando il tempo e lo sforzo richiesto a sufficienza da non valere la pena che qualcuno lo faccia. Quindi, se non disponi di enormi quantità di dati finanziari e / o finanziari e non sei una società di alto profilo, un'implementazione di sicurezza standard come quella sopra dovrebbe andar bene.

    
risposta data 09.09.2012 - 10:19
fonte
2

In JEE abbiamo la nozione di sicurezza gestita da container. In tal caso, ho configurato i miei servizi di assistenza per l'utilizzo dell'autenticazione di base, che per impostazione predefinita utilizza l'autenticazione della password HTTP rispetto a un set di autenticazione sul server dell'app. Ciò ignora la necessità di un modulo HTML per l'accesso o la complessità della distribuzione dei certificati lato client.

L'applicazione presume che ci sarebbe un utente principale e forse altri dati come i dettagli di identificazione che sono passati con la richiesta. Questo include le API riposanti.

Nella mia configurazione, ho implementato un modulo di autenticazione del server JASPIC OAuth2 [ Source ] che memorizza il token OAuth che è simmetricamente crittografato dove la chiave risiede nel server che ha anche un vita limitata nel cookie e lo usano come autenticazione per l'applicazione.

Facendo quanto sopra tengo l'applicazione lontana dalla semantica dell'autenticazione e come bonus quando voglio eseguire test di integrazione funzionale usando Selenium, sono in grado di eseguire il downgrade usando le password HTTP invece di avere un test complesso che si connette a un provider OAuth tutto il tempo.

Inoltre, continuerò a utilizzare SSL per garantire che il trasporto sia perlomeno sicuro. Non usare SSL aggiunge troppa complessità nell'affrontare attacchi comuni alla tua applicazione.

Tieni presente che questo è un JEE ma i meccanismi possono essere applicati a qualsiasi tecnologia.

    
risposta data 08.07.2014 - 08:15
fonte
2

Non sarai mai sicuro al 100% che la tua API sia sicura.

La ragione principale di questo è che stai probabilmente consegnando un file binario ai tuoi clienti / utenti che semplicemente funziona. Quindi hanno tutto il tempo del mondo per analizzare quel binario per cercare chiavi / segreti su di esso, usati per autenticare in sicurezza sul tuo server API. L'endpoint dell'API del client è il punto più debole, poiché è il proprietario del dispositivo su cui viene eseguito il binario, pertanto può manipolare i certificati ritenuti validi o meno dal dispositivo.

Un chiaro esempio di ciò di cui sto parlando è questo articolo ("Un tutorial per Reverse Engineering API privata del tuo software: Hacking Your Couch"). E vorrei finalizzare questa risposta citando uno degli ultimi paragrafi in esso:

Is it possible to completely prevent usage of a private API by third-party clients? I don’t think so. Using SSL pinning would prevent sniffing into API requests using a simple transparent proxy technique as described earlier. In the end, even if you obfuscate the binary, a motivated hacker with some resources and time will always be able to reverse-engineer the app binary and get the private key/certificate. I think the assumption that the client endpoint is secure is inherently wrong. An API client is a weak spot.

    
risposta data 02.07.2016 - 10:13
fonte
1

Solo HTTPS è obbligatorio.

Mentre controlli sia l'app che l'api, implementerei l'Apposizione di certificati. Il blocco del certificato può essere sconfitto, ma è un buon deterrente contro l'ispettore occasionale.

Puoi aggiungere un altro livello con Payload Encryption. Ciò comporta un solido processo di Key Distribution e Key Rotation.

Se la tua app utilizza token di accesso o cookie di sessione per l'autorizzazione a specifiche API, assicurati che scada. Spesso osservo token al portatore che non scadono per giorni, mesi o mai.

Regola d'oro: un O / S mobile è un ambiente ostile. Tratta con cura e amp; una mancanza di fiducia.

    
risposta data 18.07.2016 - 15:16
fonte

Leggi altre domande sui tag