¿Qué tan único es el ID de sesión de php?

90

¿Qué tan único es el ID de sesión de php? Varias cosas que he leído me dan la impresión de que no debería confiar en que dos usuarios nunca obtengan el mismo ID de sesión. ¿No es un GUID?

Jalov
fuente

Respuestas:

39

De hecho, Session_id se puede duplicar, pero la probabilidad es muy baja. Si tiene un sitio web con un tráfico justo, puede suceder una vez en la vida de su sitio web y solo molestará a un usuario por una sesión.

No vale la pena preocuparse por esto a menos que espere construir un sitio web de mucho tráfico o un servicio para la industria bancaria.

e-satis
fuente
4
He escuchado informes de sitios que han tenido muchos casos de colisiones.
ColinM
20
La pregunta se hizo hace casi 4 años. Sería interesante saber si el algoritmo de identificación de sesión se ha improvisado desde entonces ...
Sliq
@ColinM: y esos sitios tenían 1 millón de visitantes únicos / día.
e-satis
1
Evidentemente, se basa actualmente (hash MD5 / SHA1) en la dirección remota del usuario, la hora local y algún número aleatorio (LCG) .
Caramiriel
2
No necesito romper el móvil, el móvil se rompe constantemente. :)
hakre
67

No es muy exclusivo como se envía. En la configuración predeterminada, es el resultado de un hash de varias cosas, incluido el resultado de gettimeofday (que no es terriblemente único), pero si está preocupado, debe configurarlo para extraer algo de entropía de / dev / urandom, así

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

busque "php_session_create_id" en el código para el algoritmo real que están usando.

Editado para agregar: hay un generador de números aleatorios DFA sembrado por el pid, mezclado con el tiempo en usecs. No es una condición de singularidad firme, especialmente desde una perspectiva de seguridad . Utilice la configuración de entropía anterior.

Actualizar:

A partir de PHP 5.4.0 session.entropy_file tiene como valor predeterminado / dev / urandom o / dev / arandom si está disponible. En PHP 5.3.0, esta directiva se deja vacía por defecto. Manual de PHP

djsadinoff
fuente
1
Sí, cuando tenía un contrato para un sitio web que tenía que ser ultraseguro contra combatientes enemigos y demás, de hecho creé mi propio controlador de sesión y lo alimenté con datos de entropía directamente desde random.org. Pero los requisitos de ese sistema estaban mucho más allá de lo que la mayoría de los simples mortales tratan con ;-)
Theodore R. Smith
1
@ thomas-jensen, gettimeofday es la marca de tiempo de Unix, excepto que se expresa en μseg (a veces). Lea el método php_session_create_id vinculado anteriormente.
djsadinoff
4
Cambiar la longitud de la entropía mejora la aleatoriedad pero no afecta significativamente la probabilidad de una colisión, ya que el hash sigue teniendo la misma longitud. Sin embargo, cambiar session.hash_function le permite usar hash más largos como sha512, por ejemplo.
ColinM
2
Me parece extraño que haya colisiones. Seguramente se debe hacer PHP para verificar si hay una sesión válida bajo esa identificación y posteriormente generar una identificación diferente ..
Lucas
1
@ theodore-r-smith, es una mala práctica tomar la entropía de una fuente disponible públicamente. Debes asumir que tus "combatientes enemigos" también tienen acceso a random.org ...
avri
12

Si desea saber cómo PHP genera una ID de sesión de forma predeterminada, consulte el código fuente en Github . Ciertamente no es aleatorio y se basa en un hash (predeterminado: md5) de estos ingredientes (vea la línea 310 del fragmento de código):

  1. Dirección IP del cliente
  2. Tiempo actual
  3. Generador de congruencia lineal PHP : un generador de números pseudoaleatorios (PRNG)
  4. Fuente aleatoria específica del sistema operativo: si el sistema operativo tiene una fuente aleatoria disponible (por ejemplo, / dev / urandom)

Si el sistema operativo tiene una fuente aleatoria disponible, entonces la fuerza de la ID generada con el propósito de ser una ID de sesión es alta ( / dev / urandom y otras fuentes aleatorias del sistema operativo son (generalmente) PRNG criptográficamente seguras ). Sin embargo, si no es así, es satisfactorio.

El objetivo de la generación de identificación de sesión es:

  1. minimizar la probabilidad de generar dos ID de sesión con el mismo valor
  2. hace que sea muy difícil computacionalmente generar claves aleatorias y presionar una en uso .

Esto se logra mediante el enfoque de PHP para la generación de sesiones.

No puede garantizar absolutamente la singularidad , pero las probabilidades de acertar el mismo hash dos veces son tan bajas que, en términos generales, no vale la pena preocuparse.

GordyD
fuente
11

Puede instalar una función de generación de hash alternativa si desea personalizar la forma en que se genera la ID (es un número de 128 bits generado a través de MD5 de forma predeterminada). Ver http://www.php.net/manual/en/session.configuration.php#ini.session.hash-function

Para obtener más información sobre las sesiones de PHP, pruebe este excelente artículo http://shiflett.org/articles/the-truth-about-sessions que también contiene enlaces a otros artículos sobre la fijación y el secuestro de sesiones.

Paul Dixon
fuente
2
Para ser exactos, configure "session.hash_function = sha512" para PHP 5.3 y superior para ir al hash de 512 bits. Esto debería funcionar. Con los valores predeterminados, ES común en sitios de alto tráfico tener colisiones.
ColinM
5

Tamaño de session_id
Suponga que seeion_id está distribuido uniformemente y tiene un tamaño = 128 bits. Suponga que todas las personas del planeta inician sesión una vez al día con una nueva sesión persistente durante 1000 años.

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 

Entonces, la probabilidad de una o más colisiones es menos de uno en 70 mil billones. Por lo tanto, el tamaño de 128 bits del session_id debería ser lo suficientemente grande. Como se mencionó en otros comentarios, session_manager también puede verificar que el nuevo session_id aún no existe.

Aleatoriedad
Por lo tanto, la gran pregunta que creo es si los session_id: s se generan con una buena pseudoaleatoriedad. De eso nunca puede estar seguro, pero recomendaría usar una solución estándar bien conocida y de uso frecuente para este propósito (como probablemente ya lo haga).

Incluso si se evitan las colisiones debido a la verificación, la aleatoriedad y el tamaño de session_id es importante, por lo que los piratas informáticos no pueden, de alguna manera, realizar conjeturas calificadas y encontrar session_id: s activos con gran probabilidad.

MrJ
fuente
3
No soy matemático, pero creo que te estás olvidando del problema del cumpleaños, por lo que las posibilidades de colisión cuando aún son pequeñas son mucho mayores de lo que sugieres. Además, como sugirió djsadinoff, PHP no necesariamente usa un buen método para generar números aleatorios por defecto.
ColinM
No, en realidad, la estimación se mantiene. El cálculo anterior es una estimación simplificada, donde estimamos que la probabilidad de una colisión para session_id nr i, es = 1/2 82 (debería ser 1/2 92 por encima de = error tipográfico). En realidad, la probabilidad es (i-1) / 2 128 siempre que no hayan ocurrido colisiones previas. 1/2 92 se mantiene solo para el último session_id.
MrJ
3

No he encontrado una confirmación sobre esto, pero creo que php verifica si ya existe una identificación de sesión antes de crear una con esa identificación.

El problema del secuestro de sesiones que preocupa a la gente es cuando alguien descubre la identificación de sesión de un usuario activo. Esto se puede prevenir de muchas maneras, para obtener más información al respecto, puede ver esta página en php.net y este documento sobre la fijación de sesiones.

Ólafur Waage
fuente
2
... pero si solo es un servidor php en un banco de varios, no hay garantía de que el servidor tenga el conocimiento suficiente para saber si se ha utilizado el ID de sesión.
djsadinoff
¿Por qué importaría si obtuviera la misma identificación de sesión en 2 servidores php diferentes? Suponiendo 2 dominios diferentes, la cookie de sesión solo es accesible desde cada dominio ...
daremon
3
La forma más sencilla de evitar engaños en un entorno de varios servidores es almacenar las sesiones en memcached a través del controlador de sesiones de memcached. problema resuelto y sus usuarios pueden rebotar alrededor de los servidores diff sin perder sus cosas.
Theodore R. Smith
@daremon está hablando de varios servidores para un dominio.
gtd
Esto es simplemente incorrecto. PHP no comprueba los identificadores de sesión existentes al generar nuevos. Mire cualquier código de controlador de sesión PHP y simplemente no hay ningún método implementado para este propósito.
ColinM
2

No, el ID de sesión no es un GUID, pero dos usuarios no deben obtener el mismo ID de sesión ya que están almacenados en el lado del servidor.

artilugio
fuente
2
Posiblemente porque el almacenamiento del lado del servidor no garantiza la exclusividad de ninguna manera. La singularidad es una cosa: si hay una colisión, colisionará independientemente de dónde se almacene la sesión.
No por mí, agradezco tu respuesta (así como la de los demás). - Jalov
Jalov
2
La ID de sesión se almacena tanto en el servidor como en el cliente. El contenido de la sesión se almacena en el lado del servidor. Y el hecho no está relacionado con la unicidad del ID de sesión.
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>

si su nombre de usuario es diferente o único, puede usar este código para la sesión

Arun Sharma
fuente