Protezione dell'API REST senza HTTPS

4

Sto sviluppando un'API REST ma non riesco a utilizzare HTTPS senza utilizzare certificati autofirmati . Capisco che potrebbe essere accettabile per alcuni, ma non voglio che i messaggi di sicurezza saltino fuori sui browser dei client.

Le informazioni trasmesse sulla rete non sono sensibili, quindi non mi interessa l'intercettazione, ma voglio assicurarmi che solo i client autorizzati siano in grado di effettuare richieste e prevenire attacchi di riproduzione. Ecco la mia idea:

Un utente è registrato con l'applicazione Web che esegue il servizio. Vogliono registrare un client API, ma non sono uno sviluppatore, quindi scaricano un'applicazione client fornita (in questo caso, un lettore di schede IC che utilizzeranno con un computer in grado di comunicare i dati letti dalle carte scansionate al servizio web tramite l'API).

Passaggio uno : l'applicazione client API genera una coppia di chiavi (ad esempio OpenSSL) e invia la chiave pubblica al server (può trattarsi di un passaggio di caricamento manuale quando l'utente registra il client con il server ). Il server memorizza la chiave pubblica nel database associato all'utente e una descrizione del client (ad esempio "IC Card Reader su PC01").

Perché voglio usare una coppia di chiavi (come SSH)? Sento che un segreto condiviso è vulnerabile alle intercettazioni perché deve essere trasferito sulla rete almeno una volta. Mentre questo potrebbe essere evitato inserendo manualmente la chiave sul terminale del server anziché trasportarlo sulla rete, un obiettivo di progettazione del sistema è quello di consentire agli utenti diversi da me di registrare i client e ottenere un token di accesso API utilizzando l'interfaccia web per il applicazione. In questa circostanza, un intercettatore potrebbe intercettare una chiave segreta condivisa, mentre una coppia di chiavi generata dal client lo impedirebbe.

Passaggio due : quando si effettua una richiesta, il client ottiene prima un nonce dal server (che lo memorizza in un elenco o database di nonces e timestamp emessi) e quindi effettua la richiesta incluso il nonce mentre firmando la richiesta con la loro chiave privata. Il server verifica che il messaggio sia autentico (è stato firmato dal client e nessun altro) prima dell'esecuzione della richiesta.

Il mio obiettivo con questo approccio è quello di garantire che solo i client validi stiano accedendo all'API, impedendo allo stesso tempo gli attacchi di riproduzione. Un utente malintenzionato dovrebbe essere in grado di vedere il contenuto dei messaggi (non molto sensibile), ma non dovrebbe essere in grado di modificarli. Al cliente non importa se i dati provenienti dal server sono autentici (perché in questo caso il client sta cambiando lo stato del server, non il contrario).

  • Questo approccio soddisfa questi obiettivi di progettazione?
  • E impedisce contro gli attacchi man-in-the-middle (assumendo l'originale la registrazione del cliente era con il server reale e non un quello falso dell'attaccante)?
posta Aaron D 11.07.2015 - 15:31
fonte

4 risposte

2

Tieni presente che HTTPS (senza l'autenticazione del client) in realtà non ti aiuterà a raggiungere il tuo obiettivo di:

My goal with this approach is to ensure that only valid clients are accessing the API, while also preventing replay attacks.

HTTPS (senza autenticazione client) impedirà ai tuoi clienti di parlare con qualcuno che impersona il tuo server; non impedirà a qualcuno di impersonare i client di parlare con un vero server.

Quindi, anche se riesci ad ottenere un certificato TLS appropriato, dovrai comunque adottare alcune misure di sicurezza per raggiungere gli obiettivi dichiarati.

Does this approach meet these design goals?

Direi di sì, a condizione che:

    il server
  • applica correttamente l'unicità di nonce e impedisce il riutilizzo nonce;
  • Il client
  • include quel nonce in risposta e firma la risposta completa , inclusi URI, intestazioni, carico utile.

Puoi utilizzare le firme asimmetriche (come da te proposte) o quelle simmetriche (ad esempio HMAC). Entrambi gli approcci dovrebbero funzionare a patto che sia possibile garantire che lo scambio iniziale (chiave pubblica o caricamento segreto condiviso) avvenga su un canale sicuro. Amazon preferisce HMAC e questa libreria supporta RSA, DSA e HMAC.

And does it prevent against man-in-the-middle attacks (assuming the original registration of the client was with the real server and not an attacker's fake one)?

Dipende. L'hacker è ancora in grado di impersonare il server e fornire dati dannosi al client (perché il client non autentica il server in alcun modo: questa è la parte in cui HTTP potrebbe aiutare).

Allo stesso tempo, se è possibile garantire che lo scambio iniziale dei dati di autenticazione (chiave pubblica in caso di RSA o segreto condiviso in caso di HMAC) sia stato eseguito su canale sicuro, allora il server dovrebbe essere in grado di rilevare e rifiutare qualsiasi manomissione risposte (vale a dire quelle con nonce o firma non valide) e ciò fornisce l'autenticazione del client resistente al MITM.

Questa parte dovrebbe essere valutata molto attentamente per quanto riguarda i flussi di protocollo (chi inizia la richiesta, quali sono i flussi di dati, ecc.) perché il client non ha mezzi per autenticare il server.

    
risposta data 13.07.2015 - 00:18
fonte
4

My goal with this approach is to ensure that only valid clients are accessing the API, while also preventing replay attacks.

Utilizza un valore nonce sempre crescente.

An attacker should be able to see the contents of the messages (not really sensitive), but should be unable to modify them.

Hai una chiave API e un segreto.

Le tue richieste contengono la chiave in testo semplice.

Includono anche un valore "hash". Questo valore di hash è un hash (ad esempio, sha256) della concatenazione del segreto dell'API, il valore nonce sempre crescente e i dati della richiesta stessa. Il server genera il proprio hash e lo confronta con quello inviato dal client.

Un utente malintenzionato può leggere la tua richiesta API, ma dal momento che non ha la sua API segreta, non sarà in grado di creare un nuovo valore di "hash" e di inviare i propri dati arbitrari. Inoltre, non sarà in grado di riprodurre vecchie chiamate API a causa del tuo valore nonce.

    
risposta data 11.07.2015 - 18:04
fonte
1

No, non impedisce un attacco MITM. Non è possibile avere l'autenticazione del client senza l'autenticazione del server. Il motivo per cui il cliente ha la certezza che stia parlando anche con il tuo server e il tuo server non ha alcuna garanzia che stia effettivamente parlando al client.

Senza autenticare il server questo:

Client < -------- > Server

è identico a questo:

Client < ----- > MITM < -------- > Server

Il MITM può modificare qualsiasi cosa inviata dal server al client o dal client al server. Il client vede solo ciò che il MITM vuole che veda e le uniche richieste che lo fanno al server sono quelle consentite dal MITM.

Quindi nel tuo esempio il client richiede un nonce, il server invia nonce (MITM fa una copia). Il client crea una richiesta, MITM lo intercetta e lo modifica a ciò che vuole e lo inoltra al server. Il server ritiene che la richiesta sia autentica.

Ora il cert autofirmato "potrebbe" essere utilizzato se si dispone di un metodo per fornire l'id (impronta digitale o chiave pubblica) al client utilizzando la comunicazione fuori banda. In questo modo il client può stabilire in modo sicuro un canale di comunicazione crittografato e autenticato con il server assicurandosi che il server ciao (parte dell'handshake SSL) corrisponda all'id "precondiviso" del certificato del server previsto.

Questo potrebbe funzionare nel tuo scenario ma nella maggior parte degli scenari porta a una situazione di uova e galline. La comunicazione è sicura SE posso ottenere in modo sicuro l'ID valido del server cert al client, ma per farlo ho bisogno di una sorta di comunicazione sicura. Il punto di CA è quello di avviare tale processo.

    
risposta data 12.07.2015 - 19:16
fonte
0

Non ho idea del motivo per cui l'OP può consentire l'accesso alla porta a 443 ma a 80. In tal caso, puoi semplicemente impostare una regola in entrata per qualsiasi porta che sia compatibile con HTTPS (qualsiasi TCP / IP è ..). Basta impostare la porta configurata e configurare un HTTPS.

Inoltre, per le API, c'è un intero set di sicurezza API in OWASP che puoi guardare. Ecco un cheatsheet che ti consente di difendere:

https://www.owasp.org/index.php/REST_Security_Cheat_Sheet

Puoi anche scegliere di implementare una buona misura di sicurezza già pronta implementando questo:

https://www.owasp.org/index.php/ESAPI_Secure_Coding_Guideline

Tutte le guide sono gestite dalla comunità OWASP. Non sei sicuro che i tuoi certificati TLS abbiano problemi con il tuo set-up, nel caso in cui lo fossero, contatta il tuo fornitore per questo supporto.

    
risposta data 12.07.2015 - 18:59
fonte

Leggi altre domande sui tag