Abbiamo un'app mobile per iOS e Android disponibile negli store Apple e Google Play. L'app comunica con i servizi Web del nostro server su HTTPS.
Abbiamo attaccanti in grado di spoofare il traffico dell'app. Questo probabilmente significa che i nostri aggressori stanno decodificando e monitorando la richiesta / risposta dei servizi Web crittografati con HTTPS con uno strumento come Fiddler .
Il nostro prossimo passo è crittografare all'interno dell'app mobile. Criptiamo il carico utile del servizio Web in entrambe le direzioni utilizzando AES in modalità CBC con HMAC. Ciò significa che sia il nostro server che l'app mobile scaricabile hanno una chiave segreta condivisa (in realtà, almeno due).
Il problema è che è abbastanza possibile decodificare le app mobili iOS o Android e raccogliere le chiavi segrete. Per essere sicuri, abbiamo un livello più alto di sicurezza. Ci vuole più esperienza per decodificare un'app mobile di quanto ci vuole per osservare il traffico HTTPS tramite Fiddler.
Potremmo non essere un bersaglio abbastanza grande da permettere a nessuno di preoccuparsi di raccogliere le nostre chiavi segrete. Ma ci piacerebbe crescere fino al punto in cui vale la pena l'attacco!
Qualsiasi protocollo di scambio di chiavi di cui sono a conoscenza richiede che l'app mobile abbia una chiave segreta da qualche parte nel processo. Con l'app disponibile come download gratuito da Apple App Store e Google Play, semplicemente non ho modo di garantire che il segreto rimanga segreto.
Arxan.com afferma di fornire una soluzione di livello Enterprise che sembra essere un processo sufficientemente complesso di occultamento delle chiavi da -se attaccanti. Non sono ancora pronto a chiedergli dei prezzi!
Considerato in un modo, la mia domanda è: "Come posso proteggere una chiave segreta in un'app mobile in the wild?" Ho visto due risposte chiare:
- Non puoi.
- Utilizza HTTPS. Tuttavia, lo facciamo e per noi è chiaro che il nostro traffico è ancora monitorato.
Quindi, penso che la mia domanda diventi un'autenticazione anziché un'autorizzazione: sul lato server, come faccio a distinguere tra un utente malintenzionato che finge di essere la nostra app mobile e il traffico legittimo dalla nostra app?
Supponendo che stiamo crittografando e utilizzando correttamente HMAC, un messaggio valido ci dice:
- Il messaggio non è stato modificato.
- Il mittente è in possesso delle nostre chiavi segrete condivise.
Tutto a questo punto dipende dalla chiave segreta non compromessa.
L'unica risposta che ho considerato fino ad ora è l'analisi del traffico. Rileviamo il traffico di attacco a forza bruta e alcuni altri profili di traffico. Rileviamo varie forme di attacco di replay.
Potremmo quindi dedurre che la nostra chiave segreta è stata compromessa, se mai lo è stata, e invalidare la chiave (invalidando così tutte le installazioni mobili in natura). Ma è ovvio che se un attaccante può capire una chiave segreta, quell'attaccante può capire anche la chiave successiva. Né vogliamo invalidare la nostra intera base utenti legittima dell'app installata!
Possiamo installare un certificato all'interno della nostra app, ma questo risolve il problema? E se sì, come? Non abbiamo lo stesso problema della decodificazione e spoofing della app?
EDIT: cosa stiamo cercando di proteggere?
-
Il nostro utente malintenzionato può eseguire una lista di password contro di noi spoofando la sequenza web di accesso utente della nostra app. Poiché il nostro aggressore è in grado di osservare il traffico HTTPS non appena esce dall'app, il nostro hacker sa come costruire la richiesta e l'autenticazione del servizio web.
-
Possiamo crittografare le informazioni di accesso (e altre) prima che lasci l'app. Questo dovrebbe impedire sia lo sniffing che lo spoofing, presumendo che il nostro aggressore non possieda le chiavi segrete utilizzate nella crittografia.
-
Dato che il traffico in entrata (verso il server) è più importante da proteggere, la crittografia a chiave pubblica sarebbe una possibilità. Solo il server potrebbe decrittografarlo. Tuttavia, poiché la chiave è pubblica, il nostro utente malintenzionato potrebbe comunque eseguire un elenco di password che finge di essere l'app.
Quindi cosa stiamo cercando di proteggere? Stiamo cercando di proteggerci da un utente malintenzionato che irrompe negli account utente tramite i nostri servizi web. Nello specifico, in che modo potremmo proteggerci da un aggressore sufficientemente motivato a eseguire il reverse engineering della nostra app mobile in natura?
SECOND EDIT: Proviamo a risolvere il problema.
Come possiamo progettare un'API Web Services solida e sicura? Deve essere in grado di resistere all'osservazione di un potenziale aggressore. Dobbiamo essere in grado di distinguere e respingere i messaggi spuri da un potenziale aggressore.
In particolare, vogliamo:
-
Impedisci al nostro aggressore di utilizzare l'API dei servizi Web per eseguire un elenco di password e potenzialmente accedere a un account membro. Disponiamo di altre misure di rilevamento della forza bruta, ma vorremmo proteggere direttamente la nostra API da tale attacco.
-
Impedisci al nostro aggressore di utilizzare la nostra API dei servizi Web per sondare il nostro server per altre possibilità di attacco.