it-swarm.dev

Autenticazione basata su token: protezione del token

Ho sviluppato un back-end REST API per un'app mobile e ora sto cercando di implementare un'autenticazione basata su token per evitare di dover richiedere all'utente di accedere ad ogni esecuzione dell'app.

Quello che avevo in mente era sulla richiesta iniziale che l'utente inviava le proprie credenziali utilizzando l'autenticazione di base su SSL. Una volta che il server ha autenticato le credenziali, crea un token sicuro e lo rispedisce all'utente in modo che possano utilizzarlo nelle richieste successive fino alla scadenza o alla revoca del token.

Sto cercando qualche consiglio su come posso generare un token che non sarà suscettibile a cose come gli attacchi MoM/Replay, oltre a garantire che i dati memorizzati all'interno del token non possano essere estratti.

Userò il seguente approccio per generare il token che penso impedirebbe l'estrazione di qualsiasi dato da esso. Tuttavia, devo ancora assicurarmi che non sia vendibile da altri attacchi.

L'API sarà accessibile solo su SSL ma non sono sicuro di poter fare affidamento esclusivamente su questo aspetto dal punto di vista della sicurezza.

99
James

Il "token di autenticazione" funziona in base al modo in cui il server lo ricorda.

Un token generico è una stringa casuale; il server mantiene nel suo database una mappatura dai token emessi ai nomi utente autenticati. I vecchi token possono essere rimossi automaticamente per evitare che il database del server cresca indefinitamente. Tale token è abbastanza buono per la sicurezza finché un utente malintenzionato non può creare un token valido con probabilità non trascurabile, un "token valido" è "un token che si trova nel database dei token emessi". È sufficiente che i valori dei token abbiano una lunghezza di almeno 16 byte e siano prodotti con una crittografia forte PRNG (es. /dev/urandom, CryptGenRandom(), Java.security.SecureRandom ... a seconda della tua piattaforma).

È possibile scaricare i requisiti di archiviazione sui client stessi. Nel paragrafo precedente, quale "memoria" dovrebbe avere il server di un token? Vale a dire il nome utente e la data di produzione del token. Quindi, crea i tuoi token in questo modo:

  • Il server ha una chiave segreta [~ # ~] k [~ # ~] (una sequenza, diciamo, di 128 bit, prodotta da un PRNG crittograficamente sicuro ).
  • Un token contiene il nome utente ( [~ # ~] u [~ # ~] ), l'ora di emissione ( [~ # ~] t [~ # ~] ) e un controllo di integrità con chiave calcolato su [~ # ~] u [~ # ~] e [~ # ~] t [~ # ~] (insieme) , digitato con [~ # ~] k [~ # ~] (per impostazione predefinita, usa HMAC con SHA-256 o SHA-1).

Grazie alla sua conoscenza di [~ # ~] k [~ # ~] , il server può verificare che un determinato token, rispedito dall'utente, è uno dei suoi o no; ma l'attaccante non può falsificare tali token.

La risposta a cui ti colleghi è in qualche modo simile, tranne per il fatto che parla di crittografia invece di MAC, e questo è:

  1. confuso;
  2. confondendo;
  3. potenzialmente insicuro;

perché la crittografia non è MAC.

82
Thomas Pornin

In breve, è necessario utilizzare un token casuale una tantum di forza crittografica e l'hash nel database.

Il token

  • deve poter essere utilizzato una sola volta,
  • deve essere utilizzabile solo per l'utente per cui è stato creato,
  • deve essere inviato solo tramite HTTPS,
  • dovrebbe avere una data di scadenza (ad esempio 7 giorni).

Una volta che l'utente accede con il token, questo non è valido e un nuovo token deve essere creato e dato all'utente. Nel caso di un token scaduto, l'utente deve effettuare nuovamente l'accesso, utilizzando le proprie credenziali reali.

Una descrizione più definitiva e lunga di queste regole è disponibile nella parte 2 di La guida definitiva all'autenticazione del sito Web basata su moduli :

I cookie di accesso persistenti (funzionalità "Ricordami") sono una zona pericolosa; da un lato, sono completamente sicuri come gli accessi convenzionali quando gli utenti comprendono come gestirli; e d'altra parte, sono un enorme rischio per la sicurezza nelle mani della maggior parte degli utenti, che li usano su computer pubblici, dimenticano di disconnettersi, non sanno cosa sono i cookie o come eliminarli, ecc.

[...]

Segui articolo "Best Practices" di Charles Miller . Non essere tentato di seguire le migliori pratiche "migliorate" collegate alla fine del suo articolo. Purtroppo, i "miglioramenti" allo schema sono facilmente contrastati (tutto ciò che un utente malintenzionato deve fare quando ruba il cookie "migliorato" è ricordare di eliminare quello precedente. Ciò richiederà all'utente legittimo di effettuare nuovamente l'accesso, creando un nuovo identificatore di serie e lasciando valido quello rubato).

E NON MEMORIZZARE IL COOKIE DI ACCESSO PERSISTENTE (TOKEN) NEL TUO DATABASE, SOLO UN TRATTAMENTO DI ESSO! Il token di accesso è equivalente alla password, quindi se un attaccante messo le mani sul tuo database, potrebbe usare i token per accedere a qualsiasi account, proprio come se fossero combinazioni di login-password in chiaro. Pertanto, utilizzare un hash salato (bcrypt/phpass) durante la memorizzazione di token di accesso persistenti.


Aggiornamento: Spiacente, ho frainteso la domanda. Il metodo che hai collegato sembra ragionevole, ma non ti proteggerà da attacchi replay o man-in-the-middle. Dovresti usare SSL insieme ad esso.

38
Polynomial

Un servizio Web API RESTful puro dovrebbe utilizzare le funzionalità standard del protocollo sottostante:

  1. Per HTTP, l'API RESTful dovrebbe comprendere e rispettare le intestazioni, i codici di stato e i metodi standard HTTP esistenti. L'aggiunta di una nuova intestazione HTTP viola i principi REST.

  2. I servizi RESTful DEVONO ESSERE STATELESS. Qualsiasi trucco, come l'autenticazione basata su token che tenta di ricordare lo stato delle precedenti richieste REST sul server, viola i principi REST.

In conclusione: ai fini dell'autenticazione/autorizzazione, è necessario utilizzare l'intestazione dell'autorizzazione HTTP. E dovresti aggiungere l'intestazione specifica dello schema di autorizzazione HTTP in ogni richiesta successiva che deve essere autenticata.

Ho sviluppato un servizio Web RESTful per l'applicazione Cisco Prime Performance Manager. Cerca su Google il documento API di Cisco Prime Performance Manager REST che ho scritto per quell'applicazione per maggiori dettagli sulla conformità dell'API RESTFul - vedi sotto. Per questa applicazione, abbiamo scelto di utilizzare lo schema di autorizzazione "Basic" HTTP per autenticare e autorizzare le richieste. E ovviamente, stiamo usando HTTPs per crittografare tutti i dati in transito dal client al server quando si utilizza l'autorizzazione HTTP.

http://www.Cisco.com/c/en/us/support/cloud-systems-management/prime-performance-manager/products-programming-reference-guides-list.html

4
Rubens Gomes