È necessario crittografare i dati della sessione?

9

Mi sono imbattuto in una classe di gestione delle sessioni in PHP che crittografa i dati della sessione nella cartella di archiviazione della sessione (ad esempio, /tmp ) e può essere decrittografata in un secondo momento nel tuo script utilizzando una chiave. Mi stavo chiedendo se è davvero necessario? Se già fai qualche prevenzione di hijack di sessione come questo (semplificato) esempio:

session_start();

if (isset($_SESSION['fingerprint']))
    if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'].'SECRETSALT'))          
        exit; // prompt for password
else
    $_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'].'SECRETSALT');

Hai ancora bisogno di crittografare i tuoi dati di sessione? Oppure la crittografia è necessaria solo se si memorizzano informazioni sensibili tramite sessioni (ad es. Informazioni personali, numero cc, credenziali)?

Inoltre, se stai convalidando se un utente è loggato o meno in un modo semplice come questo:

// login.php

if ($_POST['password'] == $db_password)
{
    $_SESSION['logged_in'] = true;
    redirect_to_protected_area();
}
else
    // show login again

// protected_area.php

if (!isset($_SESSION['logged_in']) OR !$_SESSION['logged_in'])
    exit; // prompt for password
else
    // show protected area

Quale danno può essere fatto se i dati della sessione non sono crittografati e un hacker ha visto i dati in bella vista (ad esempio, l'hash md5 dell'impronta digitale e logged_in = true ). Può effettivamente accedere a se stesso o prima deve "crackare" l'MD5?

Nota: per semplificare l'esempio è stato utilizzato md5, nella vita reale viene utilizzato un algo di hashing molto migliore.

    
posta IMB 19.08.2012 - 19:55
fonte

4 risposte

7

Non è necessario crittografarlo. Al massimo, la crittografia è una forma di offuscamento. Stai mettendo la chiave sullo stesso sistema dei dati, quindi può sempre essere trovata ed estratta.

Se decidi di crittografarlo, in realtà è abbastanza possibile farlo in PHP senza modificare ogni utilizzo di $_SESSION . Puoi utilizzare la classe SessionHandler per sostituire la normale gestione delle sessioni. La documentazione fornisce una semplice spiegazione di come è possibile crittografare i dati della sessione.

Tuttavia, avrai bisogno di un modo per creare e memorizzare la chiave attraverso la sessione. Ovviamente questo non può essere fatto attraverso il gestore di sessioni stesso, altrimenti si distribuirebbe la chiave con il testo cifrato. Il mio suggerimento sarebbe utilizzare una cache in memoria, come APC o memcache , dove il nome della chiave nella cache è l'ID di sessione.

    
risposta data 19.08.2012 - 22:32
fonte
9

Se si utilizza un framework Web ragionevole (uno con un design decente a metà), non è necessario crittografare i dati di sessione. Questa dovrebbe essere la responsabilità del framework.

Tuttavia, se stai usando PHP, non stai utilizzando un framework web ragionevole. PHP è un problema figlio per la sicurezza, in molti modi. Uno di questi modi è che, per impostazione predefinita, memorizza i dati di sessione in /tmp . Su alcuni servizi di hosting condiviso, /tmp può essere condivisa tra gli utenti. Pertanto, PHP sta memorizzando i dati di sessione in una posizione in cui altri potrebbero essere in grado di visualizzarli, senza autorizzazione. Questo è un difetto di progettazione negativo, ma hey, PHP è pieno di difetti di progettazione, è come è la vita con PHP.

Quindi, se si utilizza PHP su un servizio di hosting condiviso (dove /tmp è accessibile ad altri), sì, è necessario crittografare i dati della sessione. Un modo per farlo è utilizzare il gancio session_set_save_handler() per crittografare i dati della sessione . Assicurati di utilizzare la crittografia avanzata (usa la crittografia autenticata, evita i comuni inconvenienti di crittografia) con una buona gestione delle chiavi (per carità, non memorizzare la chiave di crittografia in /tmp o in qualsiasi altra posizione che gli altri clienti del tuo servizio di hosting condiviso possono vederla ).

Oppure, ospita la tua applicazione PHP su una macchina dedicata (ad es., una macchina virtuale dedicata, un VPS, una macchina fisica dedicata) e non lasciare che nessuno di cui non ti fidi. Oppure, se fossi in qualche modo sicuro di non memorizzare nulla di delicato nell'archivio delle sessioni, non è necessario crittografare i dati della sessione (ma questo è fragile in fase di manutenzione, poiché sarebbe facile per qualcuno aggiungere una funzione in futuro ciò accadrà aggiungendo alcune informazioni sensibili all'archivio delle sessioni senza rendersi conto delle conseguenze per la sicurezza).

Ma in realtà, una risposta migliore è: utilizzare un framework web serio e ben progettato. Gli amici non lasciano che gli amici usino il PHP nuda per problemi di sicurezza. Vedi, ad esempio, post del blog di Jeff Atwood su questo argomento .

    
risposta data 20.08.2012 - 08:03
fonte
3

Non ha molto senso se la chiave è memorizzata sul lato server - ma la chiave potrebbe provenire dal browser / utente. È più difficile accedere alla chiave in questo scenario (purché sia su SSL) anche con qualche accesso al server / codice sorgente.

I dati della sessione possono essere memorizzati sul filesystem / in un database e quindi persistono nei backup. Inoltre, su un sistema condiviso, a seconda di come è configurato, questo fornisce sicurezza in profondità per i dati di sessione - dove un account utente si associa a un sito, è facile limitare l'accesso a ssh / ftp, ma limitare l'accesso di PHP a specifici alberi di directory è un po 'più complesso (ci sono alcuni modi per aggirare open_base_dir); per l'hosting di fascia bassa, non ha alcun senso finanziario per gestire ciascun server Web come un gruppo di FPM separato / uid separato per ciascun sito.

Mentre nessuno sano di mente dovrebbe conservare i dettagli della carta di credito su tale sistema - cosa succede se si desidera semplicemente un semplice front end per invocare occasionalmente altri servizi - ad es. disponibilità di polling / prestazioni di un altro server su SSH, invio di un SMS o accesso a una casella di posta? In questi casi è abbastanza probabile che tu possa temporaneamente mantenere un token di autenticazione secondario / chiave di crittografia / identificatore di sessione remota all'interno della sessione.

Mentre è banale limitare l'accesso in scrittura ai file src di PHP a un piccolo insieme di utenti altro rispetto al uid del server web, l'uid del server web deve essere in grado di scrivere i dati della sessione. Una volta che un utente è autenticato, l'autorizzazione è in genere basata sull'ID utente autenticato memorizzato nella sessione, quindi potrebbe essere parte di una soluzione per la protezione contro l'escalation dei privilegi (necessita di altri componenti non menzionati nel post).

Aiuterà la sicurezza in alcuni casi limite a seconda di come viene gestita la chiave.

    
risposta data 21.08.2012 - 10:54
fonte
0

Sarebbe meno complicato utilizzare i cookie per memorizzare solo un ID di sessione. Il server deve quindi ricordare quale utente appartiene a quale sessione e quali autorizzazioni ha ciascun utente. Questo design ha lo svantaggio di rendere meno efficace il bilanciamento del carico perché i dati di sessione devono essere comunicati tra tutte le istanze dell'applicazione.

Una progettazione migliore sarebbe quella di consentire ai nodi di accesso di eseguire l'autenticazione e cercare le autorizzazioni degli utenti nel database. Questi dati vengono quindi restituiti al client come token con firma crittografica, che può essere memorizzato in un cookie o in un URL. La firma di questo token è necessaria poiché la crittografia non inibisce la manomissione del token. È fondamentale quindi che ogni servizio verifichi la firma prima di agire su di esso. Questa è in realtà l'idea centrale tra Token Web JSON

    
risposta data 12.10.2017 - 15:52
fonte