Quanto è unico l'id della sessione php


90

Quanto è unico l'id della sessione php? Ho avuto l'impressione da varie cose che ho letto che non dovrei fare affidamento sul fatto che due utenti non ottengano mai lo stesso sessionid. Non è un GUID?

Risposte:


39

Session_id può effettivamente essere duplicato, ma la probabilità è molto bassa. Se si dispone di un sito Web con un traffico equo, potrebbe accadere una volta nella vita del sito Web e infastidirà un utente per una sessione.

Non vale la pena preoccuparsi di questo a meno che non ti aspetti di costruire un sito web ad alto traffico o un servizio per il settore bancario.


4
Ho sentito segnalazioni di siti che hanno avuto molti casi di collisioni.
ColinM

20
La domanda è stata posta quasi 4 anni fa. Sarebbe interessante sapere se l'algoritmo dell'id di sessione si è improvvisato da allora ...
Sliq

@ColinM: e quei siti avevano 1 milione di visitatori unici al giorno.
e-satis

1
A quanto pare è attualmente basato (hash MD5 / SHA1) sull'indirizzo remoto dell'utente, l'ora locale e alcuni numeri casuali (LCG) .
Caramiriel

2
Non ho bisogno di rompere il cellulare, il cellulare si rompe costantemente. :)
hakre

67

Non è molto unico come spedito. Nella configurazione predefinita è il risultato di un hash di varie cose incluso il risultato di gettimeofday (che non è terribilmente unico), ma se sei preoccupato, dovresti configurarlo per trarre un po 'di entropia da / dev / urandom, in questo modo

ini_set("session.entropy_file", "/dev/urandom");
ini_set("session.entropy_length", "512");

cerca "php_session_create_id" nel codice per l'algoritmo effettivo che stanno utilizzando.

Modificato per aggiungere: c'è un generatore di numeri casuali DFA seminato dal pid, mescolato con il tempo in usecs. Non è una condizione di unicità costante, soprattutto dal punto di vista della sicurezza . Usa la configurazione dell'entropia sopra.

Aggiornare:

A partire da PHP 5.4.0 session.entropy_file ha come impostazione predefinita / dev / urandom o / dev / arandom se disponibile. In PHP 5.3.0 questa direttiva è lasciata vuota per impostazione predefinita. Manuale PHP


1
Sì, quando avevo un contratto per un sito Web che doveva essere ultra sicuro contro i combattenti nemici e simili, in realtà ho creato il mio gestore di sessioni e gli ho fornito dati di entropia direttamente da random.org. Ma i requisiti di quel sistema erano molto al di là di ciò che la maggior parte dei comuni mortali ha a che fare con ;-)
Theodore R. Smith

1
@ thomas-jensen, gettimeofday è il timestamp unix, tranne che è espresso in μsec (a volte). Leggi il metodo php_session_create_id collegato sopra.
djsadinoff

4
La modifica della lunghezza dell'entropia migliora la casualità ma non influisce in modo significativo sulla probabilità di una collisione poiché l'hash ha ancora la stessa lunghezza. Tuttavia, la modifica di session.hash_function consente di utilizzare hash più lunghi come sha512, ad esempio.
ColinM

2
Trovo strano che ci siano collisioni. Sicuramente PHP dovrebbe essere fatto per verificare se c'è una sessione valida sotto quell'id e successivamente generare un ID diverso ..
Luca

1
@ theodore-r-smith, è davvero una cattiva pratica prendere l'entropia da una fonte disponibile pubblicamente. Dovresti presumere che anche i tuoi "combattenti nemici" abbiano accesso a random.org ...
avri

12

Se vuoi sapere come PHP genera un ID di sessione per impostazione predefinita, controlla il codice sorgente su Github . Non è certamente casuale e si basa su un hash (predefinito: md5) di questi ingredienti (vedere la riga 310 dello snippet di codice):

  1. Indirizzo IP del client
  2. Ora attuale
  3. PHP Linear Congruence Generator - un generatore di numeri pseudo casuali (PRNG)
  4. Sorgente casuale specifica del sistema operativo - se il sistema operativo ha una sorgente casuale disponibile (ad esempio / dev / urandom)

Se il sistema operativo ha una fonte casuale disponibile, la forza dell'ID generato allo scopo di essere un ID di sessione è alta ( / dev / urandom e altre fonti casuali del sistema operativo sono (di solito) PRNG crittograficamente sicuri ). Se invece non lo fa allora è soddisfacente.

L'obiettivo con la generazione dell'identificazione della sessione è:

  1. ridurre al minimo la probabilità di generare due ID di sessione con lo stesso valore
  2. rendono molto difficile dal punto di vista computazionale generare chiavi casuali e premerne una in uso .

Ciò è ottenuto dall'approccio di PHP alla generazione di sessioni.

Non puoi garantire in modo assoluto l'unicità , ma le probabilità di ottenere lo stesso hash due volte sono così basse che, in generale, non vale la pena preoccuparsi.


11

È possibile installare una funzione di generazione hash alternativa se si desidera personalizzare il modo in cui viene generato l'ID (è un numero a 128 bit generato tramite MD5 per impostazione predefinita). Vedi http://www.php.net/manual/en/session.configuration.php#ini.session.hash-function

Per ulteriori informazioni sulle sessioni PHP, prova questo eccellente articolo http://shiflett.org/articles/the-truth-about-sessions che contiene anche collegamenti ad altri articoli sulla correzione e il dirottamento delle sessioni.


2
Per essere precisi, imposta "session.hash_function = sha512" per PHP 5.3 e versioni successive per passare all'hash a 512 bit. Questo dovrebbe fare il trucco. Con le impostazioni predefinite, è comune nei siti ad alto traffico ottenere collisioni.
ColinM

5

Dimensione di session_id
Supponiamo che seeion_id sia distribuito uniformemente e abbia dimensione = 128 bit. Supponiamo che ogni persona sul pianeta acceda una volta al giorno con una nuova sessione persistente per 1000 anni.

num_sesion_ids  = 1000*365.25 *7*10**9 < 2**36
collission_prob < 1 - (1-1/2**82)**(2**36)   1 - e**-(1/2**46) 
                 1/2**46 

Quindi la probabilità di una o più collisioni è inferiore a una su 70mila miliardi. Quindi la dimensione di 128 bit di session_id dovrebbe essere abbastanza grande. Come accennato in altri commenti, il session_manager potrebbe anche controllare che il nuovo session_id non esista già.

Casualità
Quindi la grande domanda penso sia se i session_id: s siano generati con una buona pseudo casualità. Su questo non si può mai essere sicuri, ma consiglierei di utilizzare una soluzione standard ben nota e utilizzata di frequente per questo scopo (come probabilmente già fai).

Anche se le collisioni vengono evitate grazie al controllo, la casualità e la dimensione di session_id sono importanti, in modo che gli hacker non possano, in qualche modo, fare ipotesi qualificate e trovare session_id: s attive con grande probabilità.


3
Non sono un matematico, ma penso che tu stia dimenticando il problema del compleanno, quindi le possibilità di collisione mentre sono ancora piccole sono molto maggiori di quanto suggerisci. Inoltre, come suggerito da djsadinoff, PHP non utilizza necessariamente un buon metodo per generare numeri casuali per impostazione predefinita.
ColinM

No in realtà la stima vale. Il calcolo sopra è una stima semplificata, in cui stimiamo che la probabilità di una collisione per session_id nr i, sia = 1/2 82 (dovrebbe essere 1/2 92 sopra però = errore di battitura). In realtà la probabilità è (i-1) / 2 128 fintanto che non si sono verificate collisioni precedenti. 1/2 92 vale solo per l'ultimo session_id.
MrJ

3

Non ho trovato una conferma su questo, ma credo che php controlli se esiste già un ID di sessione prima di crearne uno con quell'ID.

Il problema del dirottamento della sessione di cui le persone sono preoccupate è quando qualcuno scopre l'ID di sessione di un utente attivo. Questo può essere prevenuto in molti modi, per maggiori informazioni su questo puoi vedere questa pagina su php.net e questo documento sulla correzione della sessione


2
... ma se sei solo un server php in una banca di diversi, non c'è garanzia che il server abbia una conoscenza sufficiente per sapere se il sesssionID è stato ancora utilizzato.
djsadinoff

Perché sarebbe importante se avessi lo stesso ID di sessione in 2 server php diversi? Supponendo 2 diversi domini, il cookie di sessione è accessibile solo da ogni dominio ...?
Daremon

3
Il modo più semplice per prevenire i falsi in un ambiente multi-server è memorizzare le sessioni in memcached tramite il gestore di sessioni memcached. problema risolto e gli utenti possono rimbalzare sui server diff senza perdere le loro cose.
Theodore R. Smith

@daremon sta parlando di più server per un dominio.
gtd

Questo è semplicemente sbagliato. PHP non controlla gli ID di sessione esistenti quando ne genera di nuovi. Guarda qualsiasi codice del gestore di sessione PHP e semplicemente non esiste alcun metodo implementato per questo scopo.
ColinM

2

No, l'ID di sessione non è un GUID, ma due utenti non dovrebbero ottenere lo stesso ID di sessione poiché sono archiviati sul lato server.


2
Forse perché l'archiviazione lato server non garantisce in alcun modo l'unicità. L'unicità è una cosa: se c'è una collisione, entrerà in collisione indipendentemente da dove è memorizzata la sessione.

Non da parte mia, apprezzo la tua risposta (così come le altre). - Jalov
Jalov

2
Gli ID di sessione vengono memorizzati sia sul lato server che sul lato client. I contenuti della sessione vengono archiviati sul lato server. E il fatto non è praticamente correlato all'unicità dell'id di sessione.
YudhiWidyatama

-3
<?php
session_start();
$_SESSION['username']="username";
?>

<!DOCTYPE html>
<html>
<head>
    <title>Update</title>
</head>
<body>

<table border="2">
    <tr>
        <th>Username</th>
        <th>Email</th>
        <th>Edit</th>
    </tr>
<?php
     $conn=mysqli_connect("localhost","root","","telephasic");
     $q2="select * from register where username = '".$_SESSION['username']."'";
     $run=mysqli_query($conn, $q2);
     while($row=mysqli_fetch_array($run))
     {
         $name=$row[1];
         $email=$row[2];
     ?>

    <tr>
        <td><?php echo $name; ?></td>
        <td><?php echo $email; ?></td>
        <td><a href="edit.php"> Edit </a></td>
    </tr>
 <?php } ?>
 </table> 
 </body>

se il tuo nome utente è diverso o univoco puoi utilizzare questo codice per la sessione

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.