tipos son sesiones seguras mvc multiples las hackear funciones comprobar php security session session-cookies

son - Fijación de sesión PHP/secuestro



son seguras las sesiones php (5)

Ambos ataques de sesión tienen el mismo objetivo: obtener acceso a una sesión legítima de otro usuario. Pero los vectores de ataque son diferentes:

En ambos ataques, la ID de sesión es la información confidencial en la que se centran estos ataques. Por lo tanto, es la ID de sesión lo que debe protegerse tanto para un acceso de lectura (Secuestro de sesión) como para un acceso de escritura (Fijación de sesión).

La regla general de proteger datos confidenciales mediante el uso de HTTPS también se aplica en este caso. Además, debe hacer lo siguiente:

Para evitar ataques de fijación de sesión , asegúrese de que:

Para evitar ataques de Secuestro de sesión , asegúrese de que:

Para evitar ambos ataques de sesión, asegúrese de que:

  • para aceptar solo sesiones que su aplicación haya iniciado. Puede hacerlo tomando las huellas dactilares de una sesión al inicio con información específica del cliente. Puede usar el ID del usuario-agente pero no use la dirección IP remota o cualquier otra información que pueda cambiar entre las solicitudes.
  • para cambiar la ID de sesión usando session_regenerate_id(true) después de un intento de autenticación ( true solo en caso de éxito) o un cambio de privilegios y destruir la sesión anterior. (Asegúrese de guardar cualquier cambio de $_SESSION utilizando session_write_close antes de regenerar el ID si desea conservar la sesión asociada al ID anterior, de lo contrario, solo la sesión con el nuevo ID se verá afectada por esos cambios).
  • utilizar una implementación de vencimiento de sesión adecuada (consulte ¿Cómo expirar una sesión PHP después de 30 minutos? ).

Estoy tratando de comprender más sobre la fijación de sesión PHP y el secuestro y cómo prevenir estos problemas. He estado leyendo los siguientes dos artículos en el sitio web de Chris Shiflett:

Sin embargo, no estoy seguro de entender las cosas correctamente.

Para ayudar a prevenir la fijación de sesión, es suficiente llamar a session_regenerate_id (true); después de iniciar sesión exitosamente con alguien? Creo que entiendo eso correctamente

También habla sobre el uso de tokens pasados ​​en urls a través de $ _GET para evitar el secuestro de la sesión. ¿Cómo se haría esto exactamente? Supongo que cuando alguien inicia sesión, genera su token y lo almacena en una variable de sesión, entonces en cada página compara esa variable de sesión con el valor de la variable $ _GET.

¿Debería cambiarse este token solo una vez por sesión o en cada carga de página?

¿También es una buena manera de evitar el secuestro sin tener que pasar un valor en las direcciones URL? esto sería mucho más fácil.


Los tokens que mencionas son un "nonce": número utilizado una vez. No necesariamente tienen que usarse solo una vez, pero cuanto más tiempo se usen, mayores serán las probabilidades de que se capture y se use para secuestrar la sesión.

Otro inconveniente de nonces es que es muy difícil construir un sistema que los use y permite múltiples ventanas paralelas en la misma forma. por ejemplo, el usuario abre dos ventanas en un foro y comienza a trabajar en dos publicaciones:

window ''A'' loads first and gets nonce ''P'' window ''B'' loads second and gets nonce ''Q''

Si no tiene forma de rastrear múltiples ventanas, solo habrá almacenado un nonce - el de la ventana B / Q. Cuando el usuario luego envía su publicación desde la ventana A y pasa en nonce ''P'', este sistema rechazará la publicación como P != Q


No leí el artículo de Shiflett, pero creo que has malentendido algo.

Por defecto PHP pasa el token de sesión en la URL siempre que el cliente no acepte cookies. De lo contrario, en el caso más común, el token de sesión se almacena como una cookie.

Esto significa que si coloca un token de sesión en la URL, PHP lo reconocerá e intentará usarlo posteriormente. La fijación de sesión ocurre cuando alguien crea una sesión y luego engaña a otro usuario para que comparta la misma sesión abriendo una URL que contiene el token de sesión. Si el usuario se autentica de alguna manera, el usuario malintencionado conoce el token de sesión de un autenticado, que puede tener diferentes privilegios.

Como estoy seguro de que Shiflett explica, lo más habitual es regenerar un token diferente cada vez que cambian los privilegios de un usuario.


Ok, hay dos problemas separados pero relacionados, y cada uno se maneja de manera diferente.

Fijación de Sesión

Aquí es donde un atacante establece explícitamente el identificador de sesión de una sesión para un usuario. Normalmente en PHP se hace dándoles una url como http://www.example.com/index...?session_name=sessionid . Una vez que el atacante le da la url al cliente, el ataque es el mismo que el de un ataque de secuestro de sesión.

Hay algunas maneras de evitar la fijación de la sesión (hacer todas):

  • Establezca session.use_trans_sid = 0 en su archivo php.ini . Esto le indicará a PHP que no incluya el identificador en la URL y que no lea la URL para los identificadores.

  • Establezca session.use_only_cookies = 1 en su archivo php.ini . Esto le dirá a PHP que nunca use URLs con identificadores de sesión.

  • Vuelva a generar la ID de sesión cada vez que cambie el estado de la sesión. Eso significa cualquiera de los siguientes:

    • Autenticacion de usuario
    • Almacenar información confidencial en la sesión
    • Cambiando algo de la sesión
    • etc ...

Secuestro de sesión

Aquí es donde un atacante obtiene un identificador de sesión y puede enviar solicitudes como si fueran ese usuario. Esto significa que, dado que el atacante tiene el identificador, todos son indistinguibles del usuario válido con respecto al servidor.

No puede evitar directamente el secuestro de la sesión. Sin embargo, puede poner los pasos para que sea muy difícil y más difícil de usar.

  • Use un fuerte identificador hash de sesión: session.hash_function en php.ini . Si PHP <5.3, session.hash_function = 1 en session.hash_function = 1 para SHA1. Si PHP> = 5.3, session.hash_function = sha256 o session.hash_function = sha512 .

  • Envía un hash fuerte: session.hash_bits_per_character en php.ini . Establezca esto en session.hash_bits_per_character = 5 . Si bien esto no hace que sea más difícil de descifrar, hace una diferencia cuando el atacante intenta adivinar el identificador de sesión. La ID será más corta, pero usa más caracteres.

  • Establezca una entropía adicional con session.entropy_file y session.entropy_length en su archivo php.ini . Establezca el primero en session.entropy_file = /dev/urandom y el último en la cantidad de bytes que se leerán del archivo de entropía, por ejemplo session.entropy_length = 256 .

  • Cambie el nombre de la sesión del PHPSESSID predeterminado. Esto se logra llamando a session_name() con su propio nombre de identificador como primer parámetro antes de llamar a session_start .

  • Si eres realmente paranoico, también puedes rotar el nombre de la sesión, pero ten cuidado de que todas las sesiones se invaliden automáticamente si cambias esto (por ejemplo, si dependes de la hora). Pero dependiendo de su caso de uso, puede ser una opción ...

  • Gire el identificador de su sesión a menudo. No haría esto en todas las solicitudes (a menos que realmente necesite ese nivel de seguridad), sino en un intervalo aleatorio. Desea cambiar esto a menudo, ya que si un atacante secuestra una sesión no quiere que la pueda usar durante demasiado tiempo.

  • Incluya el agente de usuario de $_SERVER[''HTTP_USER_AGENT''] en la sesión. Básicamente, cuando comienza la sesión, guárdela en algo como $_SESSION[''user_agent''] . Luego, en cada solicitud posterior, verifique que coincida. Tenga en cuenta que esto puede ser falso, por lo que no es 100% confiable, pero es mejor que no hacerlo.

  • Incluya la dirección IP del usuario de $_SERVER[''REMOTE_ADDR''] en la sesión. Básicamente, cuando comienza la sesión, guárdela en algo como $_SESSION[''remote_ip''] . Esto puede ser problemático para algunos ISP que usan múltiples direcciones IP para sus usuarios (como lo hacía AOL). Pero si lo usa, será mucho más seguro. La única forma de que un atacante falsifique la dirección IP es poner en peligro la red en algún momento entre el usuario real y usted. Y si ponen en peligro la red, pueden hacer mucho peor que un secuestro (como ataques MITM, etc.).

  • Incluya un token en la sesión y en el lado del navegador que incremente y compare a menudo. Básicamente, para cada solicitud, haga $_SESSION[''counter'']++ en el lado del servidor. También haga algo en JS en el lado de los navegadores para hacer lo mismo (usando un almacenamiento local). Luego, cuando envíe una solicitud, simplemente tome un nonce de un token y verifique que el nonce sea el mismo en el servidor. Al hacer esto, deberías poder detectar una sesión secuestrada ya que el atacante no tendrá el contador exacto, o si lo hacen tendrás 2 sistemas que transmiten el mismo conteo y pueden decir que uno está falsificado. Esto no funcionará para todas las aplicaciones, pero es una forma de combatir el problema.

Una nota sobre los dos

La diferencia entre la Fijación de sesión y Secuestro solo se refiere a cómo se compromete el identificador de sesión. En la fijación, el identificador se establece en un valor que el atacante conoce de antemano. En Hijacking, es adivinado o robado del usuario. De lo contrario, los efectos de los dos son los mismos una vez que el identificador está comprometido.

Regeneración de ID de sesión

Siempre que regenere el identificador de sesión usando session_regenerate_id la sesión anterior debe ser eliminada. Esto ocurre de forma transparente con el controlador de la sesión principal. Sin embargo, algunos manejadores de sesión personalizados que usan session_set_save_handler() no hacen esto y están abiertos para atacar los identificadores de sesión antiguos. Asegúrese de que si está utilizando un controlador de sesión personalizado, realice un seguimiento del identificador que abre, y si no es el mismo que guarda que elimina explícitamente (o cambia) el identificador en el anterior.

Usando el manejador de sesión predeterminado, puede simplemente llamar a session_regenerate_id(true) . Eso eliminará la información de sesión anterior para usted. La ID anterior ya no es válida y hará que se cree una nueva sesión si el atacante (o cualquier otra persona para el caso) intenta usarla. Tenga cuidado con los controladores de sesión personalizados, aunque ....

Destruyendo una sesión

Si vas a destruir una sesión (al cerrar la sesión, por ejemplo), asegúrate de destruirla completamente. Esto incluye desarmar la cookie. Usando session_destroy :

function destroySession() { $params = session_get_cookie_params(); setcookie(session_name(), '''', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"] ); session_destroy(); }


Sí, podría evitar la fijación de la sesión regenerando la identificación de la sesión una vez que inicie sesión. De esta forma si el atacante no sabrá el valor de la cookie de la nueva sesión autenticada. Otro enfoque que detiene por completo el problema es set session.use_only_cookies=True en su configuración de tiempo de ejecución. Un atacante no puede establecer el valor de una cookie en el contexto de otro dominio. La fijación de la sesión depende de enviar el valor de la cookie como GET o POST.