Necessario memorizzare temporaneamente la password di terze parti

5

Un particolare servizio Web che sto scrivendo si interfaccia con un'API. Ogni chiamata API richiede l'invio del nome utente e della password dell'utente, nessun stato viene mantenuto.

Idealmente, quando si utilizza il mio servizio web l'utente inserirà il suo nome utente e password API una volta, e il mio servizio web memorizzerà tali informazioni fino alla fine della sessione. Capisco che non dovrei memorizzare la password dell'API utilizzando le sessioni PHP né in un database a causa di problemi di sicurezza. Pertanto, come posso archiviare in modo sicuro e accedere alla password per la durata della sessione?

Sarebbe sicuro crittografare la password, memorizzare la password crittografata in un cookie e la chiave di crittografia in una sessione?

Si noti che inizialmente avevo posto la domanda (senza la soluzione proposta) su SO: link Se avessi bevuto il caffè prima, avrei saputo postare qui invece che lì. Il post SO può essere eliminato, ma non da me.

La risposta data è quella che sto usando in produzione, quindi se ci sono difetti nell'approccio (memorizzare la password crittografata nella sessione PHP, la chiave di crittografia nel cookie) allora mi piacerebbe molto sapere.

$encryptionKey = sha1(microtime(true).mt_rand(PHP_INT_MAX / 10, PHP_INT_MAX));
$encryptedPassword = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryptionKey, $password, MCRYPT_MODE_CFB);
setcookie('atwood', $encryptionKey, 0);
$_SESSION['encryptedPassword'] = $encryptedPassword;

$password = mcrypt_decrypt(MCRYPT_BLOWFISH, $_COOKIE['atwood'], $_SESSION['encryptedPassword'], MCRYPT_MODE_CFB);
    
posta dotancohen 26.02.2013 - 09:36
fonte

1 risposta

5

La domanda da porsi è: qual è il modello di sicurezza qui?

A quanto pare, è necessario trasmettere la password dell'utente (un dato sensibile) dall'utente ai server back-end. Ma la tempistica conta: l'utente umano inserisce la sua password una volta , all'inizio di ciò che l'utente pensa come "la sessione", e la password deve essere trasmessa in momenti successivi al back-end (le "chiamate API"). Quindi deve esserci un po 'di spazio di archiviazione.

Le sessioni PHP sono storage lato server, come una raccolta di piccoli file con scadenza temporale. Ciò che scrivi in una "variabile di sessione" finisce in ultima analisi sul disco rigido. Pertanto, potrebbe essere considerato come una cattiva forma per memorizzare una password semplice in una variabile di sessione, poiché il contenuto fisico del disco rigido non viene distrutto in modo affidabile quando il file viene eliminato (dopo l'eliminazione, l'area di memoria dedicata al file è contrassegnata come riutilizzabile, ma i dati stessi non verranno sovrascritti fino a quando l'area verrà effettivamente riutilizzata per un altro file). Ma ci sono dettagli:

  • Se temi una perdita di dati attraverso l'accesso post-mortem a un vecchio disco (o un nastro di backup), allora cosa vuoi evitare di inviare il file sul supporto fisico. Alcune persone mettono i file di sessione PHP su un disco RAM : il disco RAM è configurato con le strutture del sistema operativo per tali cose, e il percorso è regolato con session_save_path() . I file in un disco RAM non vengono mai salvati nell'archiviazione fisica, quindi viene segnalata la perdita. D'altra parte, tutte le sessioni andranno perse se il server si riavvia (probabilmente è tollerabile, ma dipende dalla configurazione). Condividere la sessione su più front-end sarebbe anche più complesso.

    Nota: su sistemi Linux, ci sono tre modi per creare dischi RAM: i dischi "veri" della RAM (dimensioni fino a 16 MB ciascuno, regolati al momento dell'avvio ), "ramfs" e "tmpfs". Quest'ultimo userà la RAM ma anche lo spazio di scambio, quindi i contenuti potrebbero continuare a colpire il disco. Vedi questa pagina per alcuni dettagli.

  • Se temi la perdita di dati di sessione attraverso un attacco live del tuo server, allora considera che qualcuno che potrebbe ottenere l'accesso in lettura ad alcuni file protetti da OS probabilmente non è lontano dal prendere il controllo della macchina completa, a quel punto si limiterà a collegarsi al motore PHP e ad afferrare le password degli utenti non appena arrivano. Non ha molto senso andare a quel livello di protezione.

    Quello che suggerisci è crittografare la password dell'utente e memorizzare la chiave nel browser client (come cookie) e la password crittografata nei file di sessione; oppure si potrebbe fare il contrario (digitare la sessione PHP, password crittografata nel cookie). In entrambi i casi, l'idea è che l'attaccante abbia bisogno di prendere sia i dati della sessione sia il cookie per svelare la password. Questo ha senso solo se il tuo modello di sicurezza presuppone che un utente malintenzionato sia in grado di leggere i file di sessione (anche quando si trovano solo su un disco RAM) ma non la RAM allocata al motore PHP (attraverso cui le password viaggiano necessariamente in un determinato momento) . Questo non mi sembra un modello molto realistico.

Se fai vuoi usare la crittografia, indipendentemente dalla sua apparente inutilità in quella specifica situazione, puoi anche farlo correttamente:

  • Genera la chiave (specifica dell'utente) con un PRNG protetto da crittografia ( openssl_random_pseudo_bytes() ).
  • Utilizza la crittografia corretta. Questo significa il solito assortimento di modalità di crittografia, IV casuale (da memorizzare lungo il file crittografato), padding ... che è facile da ottenere completamente sbagliato. È possibile fare la crittografia corretta con PHP, ma devi capire quello che stai facendo fino ai minimi dettagli. Nel caso specifico in cui viene generata una nuova chiave per ogni istanza di crittografia, dovrebbe essere sufficiente utilizzare un cifrario a blocchi strong in modalità CFB e una IV convenzionale fissa, anche se perderebbe la password lunghezza ; e PHP ha l'abitudine di fare cose strane (ad esempio la sua modalità "CFB" è in realtà CFB con feedback a 8 bit , che è lenta e di sicurezza discutibile per input lunghi).

ma continuo a raccomandare di non farlo, e invece di utilizzare la memorizzazione basata su RAM di sessioni PHP sul server.

    
risposta data 26.02.2013 - 13:29
fonte

Leggi altre domande sui tag