Dividi un JWT tra payload e firma
Contesto: sto cercando soluzioni di archiviazione per i token JWT su un'applicazione a pagina singola.
- La memorizzazione del JWT nella memoria locale non è sicura e soggetta ad attacchi XSS.
- La memorizzazione del JWT in un cookie protetto / solo HTTP è più sicura, ma soggetta ad attacchi CSRF.
Sto studiando il seguente scenario:
Dopo l'autenticazione, un token di aggiornamento viene memorizzato in un cookie protetto solo http. Può essere utilizzato solo per ottenere un token di accesso.
Dopo l'autorizzazione, il backend risponde con un token di accesso JWT. L'intestazione e la parte del carico utile del JWT si trovano all'interno del corpo della risposta. La firma del token non viene inviata ed è impostata in un cookie protetto solo http (rigoroso per lo stesso sito se possibile, ma supponiamo che non sia il caso). L'intestazione + il carico utile vengono archiviati in memoria.
Il JWT contiene le seguenti affermazioni
- iat, nbf, exp (IMO ipotizzabile)
- attestazioni relative all'identità e alle autorizzazioni dell'utente (ipotizzabili se l'identità dell'utente è nota)
- jti, contenente un numero casuale crittograficamente sicuro (nel mio caso generato con segreti python )
Quando si effettuano richieste, l'intestazione + il payload vengono inviati tramite XHR / fetch dalla SPA in un'intestazione di autorizzazione. La firma viene inviata insieme ai cookie. Il backend concatena entrambi e verifica la firma.
- Questo meccanismo è sicuro contro gli attacchi CSRF? Le affermazioni jti rendono il token di autorizzazione + il cookie della firma una tecnica di mitigazione CSRF valida?
- Questo meccanismo è davvero più sicuro contro gli attacchi XSS rispetto alla memorizzazione del JWT all'interno della memoria locale? (Un attacco che utilizza XSS potrebbe anche rubare facilmente la firma, come con un exploit TRACE ).
Nota: ho letto questa domanda che è simile, ma eccessivamente ampia, quindi la sto postando per ottenere una risposta più precisa.
Risposte
Questo meccanismo è sicuro contro gli attacchi CSRF?
Questo metodo di dividere un JWT e memorizzare la firma nel cookie e il resto del token in Browser Storage non fornisce alcuna protezione aggiuntiva contro gli attacchi CSRF rispetto a quando l'intero JWT fosse archiviato in Local o Session Storage. Sì, mitigherà gli attacchi CSRF, ma non è necessario aggiungere il sovraccarico non necessario della suddivisione e della concatenazione di JWT sul server. Archiviare i JWT nella memoria locale e accettarli solo nelle intestazioni di autorizzazione è sufficiente per proteggere la tua applicazione dagli attacchi CSRF.
Questo meccanismo è davvero più sicuro contro gli attacchi XSS rispetto alla memorizzazione del JWT all'interno della memoria locale? (Un attacco che utilizza XSS potrebbe anche rubare facilmente la firma, come con un exploit TRACE)
Se il tuo obiettivo è esclusivamente che un utente malintenzionato sia in grado di rubare JWT, questo approccio è sicuro a meno che, come giustamente accennato, TRACE non sia abilitato sul server.
Tuttavia, ciò non rende l'applicazione più sicura dagli attacchi XSS. Ad esempio, se sono in grado di eseguire JavaScript arbitrario sulla tua applicazione, posso recuperare l'intestazione JWT + il payload dall'archiviazione locale e inviare semplicemente un XHR a un endpoint sensibile mantenendo le credenziali impostate su True. Questo endpoint potrebbe essere progettato modificando l'indirizzo e-mail dell'account, ad esempio. Ciò porta immediatamente a un'acquisizione dell'account. Non c'è bisogno di rubare biscotti o JWT.
Riassumendo: questo approccio fornisce una certa protezione contro i token di sessione separando la firma dal resto del token. Tuttavia, quando si tratta di XSS, rubare i token di sessione non è l'unico rischio che dovresti considerare.