2009-08-03 10 views
18

Actualmente cuando el usuario ha iniciado sesión, creé 2 sesiones.¿Qué necesito para almacenar en la sesión php cuando el usuario ha iniciado sesión?

$_SESSION['logged_in'] = 1; 
$_SESSION['username'] = $username; // user's name 

Así que, los que la página que requiere conectado, acabo de hacer esto:

if(isset($_SESSION['logged_id'])){ 
// Do whatever I want 
} 

¿Hay alguna agujeros de seguridad? Quiero decir, ¿es fácil hackear mi sesión? ¿Cómo la gente piratea la sesión? y cómo lo evito?

EDIT:

Sólo encontraron esta:

http://www.xrvel.com/post/353/programming/make-a-secure-session-login-script

http://net.tutsplus.com/tutorials/php/secure-your-forms-with-form-keys/

acaba de encontrar los enlaces, son aquellos métodos suficientemente bueno ?? Por favor da tu opinión Todavía no tengo la mejor respuesta todavía.

Respuesta

46

Terminología

  • usuario: un visitante.
  • Cliente: Un software particular con capacidad web instalado en una máquina en particular.

Sesiones Comprensión

Para entender cómo hacer que su sesión segura, primero hay que entender cómo funcionan las sesiones.

Vamos a ver este pedazo de código:

session_start(); 

Tan pronto como se llama eso, PHP buscará una cookie llamada PHPSESSID (por defecto). Si no se encuentra, se creará uno:

PHPSESSID=h8p6eoh3djplmnum2f696e4vq3 

si se encuentra, se toma el valor de PHPSESSID y luego carga la sesión correspondiente. Ese valor se llama session_id.

Eso es lo único que el cliente sabrá. Todo lo que agregue a la variable de sesión permanece en el servidor y nunca se transfiere al cliente. Esa variable no cambia si cambia el contenido de $_SESSION. Siempre permanece igual hasta que lo destruyas o se agote. Por lo tanto, es inútil intentar ofuscar el contenido $_SESSION al mezclarlo o por otros medios ya que el cliente nunca recibe o envía esa información.

Entonces, en el caso de una nueva sesión, establecerá las variables:

$_SESSION['user'] = 'someuser'; 

El cliente nunca va a ver esa información.


El problema

un problema de seguridad puede surgir cuando un usuario malicioso roba la session_id de otro usuario. Sin algún tipo de control, él será libre de hacerse pasar por ese usuario. Necesitamos encontrar una manera de identificar de manera única al cliente (no al usuario).

Una estrategia (la más efectiva) consiste en verificar si la IP del cliente que inició la sesión es la misma que la de la persona que la usa.

if(logging_in()) { 
    $_SESSION['user'] = 'someuser'; 
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR']; 
} 

// The Check on subsequent load 
if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) { 
    die('Session MAY have been hijacked'); 
} 

El problema con esta estrategia es que si un cliente utiliza un equilibrador de carga, o (en la sesión de larga duración) el usuario tiene una dirección IP dinámica, se disparará una alarma falsa.

Otra estrategia consiste en comprobar el agente de usuario del cliente:

if(logging_in()) { 
    $_SESSION['user'] = 'someuser'; 
    $_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT']; 
} 

// The Check on subsequent load 
if($_SESSION['agent'] != $_SERVER['HTTP_USER_AGENT']) { 
    die('Session MAY have been hijacked'); 
} 

La desventaja de esta estrategia es que si las actualizaciones de cliente que es navegador o instala un complemento (algunos se suma a la de agente de usuario), la cadena de agente de usuario cambiará y activará una alerta falsa.

Otra estrategia es rotar el session_id en cada 5 solicitudes. De esta forma, el session_id teóricamente no permanece el tiempo suficiente para ser secuestrado.

if(logging_in()) { 
    $_SESSION['user'] = 'someuser'; 
    $_SESSION['count'] = 5; 
} 

// The Check on subsequent load 
if(($_SESSION['count'] -= 1) == 0) { 
    session_regenerate_id(); 
    $_SESSION['count'] = 5; 
} 

Puede combinar cada una de estas estrategias como lo desee, pero también combinará las desventajas.

Lamentablemente, ninguna solución es infalible. Si su session_id está comprometido, está prácticamente acabado. Las estrategias anteriores son solo medidas para detenerse.

+0

Cool. Creo que su método funciona mejor, no hay dudas al respecto. ¿Qué pasa si, combino el cheque, primero compruebo si el usuario inició sesión, verifico si el IP coincide con el IP de la sesión y verifico si el agente de usuario coincide con el agente de usuario de la sesión? ¿Es inútil? Solo necesito usar 1 de ella issit ?? – bbtang

+0

BTW, basado en la respuesta koen. Parece que session_regenerate_id() es otra buena cosa, ¿eh? ¿Puedo hacerlo de esta manera, después de que el usuario haya iniciado sesión, session_start() y luego llame a sessio_regenerate_id() ?? ¿Es bueno o es inútil (solo cosas extra)? – bbtang

+0

** @ bbtang: ** La combinación de ambos métodos también combinará sus desventajas. Puedes hacerlo a tu discreción. –

1

Puede robar sesiones mediante javascript (XSS-> crossside scripting attack) .. Siempre debe usar salado MD5 Hash para asegurar su sesión.

Para evitar el robo de sesiones, se debería poner el agente de usuario

$ _SERVER [ 'HTTP_USER_AGENT']

en la tabla hash también.

En su ejemplo:

$_SESSION['logged_in'] = 1; 
$_SESSION['username'] = $username; // user's name 
$_SESSION['hash']  = md5($YOUR_SALT.$username.$_SERVER['HTTP_USER_AGENT']); // user's name hashed to avoid manipulation 

Antes de utilizar la sesión, asegúrese de que utiliza el hash correcto:

if (!$_SESSION['hash']==md5($YOUR_SALT.$username.$_SERVER['HTTP_USER_AGENT'])){ 
    die ('session hash not corrected') 
} 
+0

Okay. Parece que tu respuesta fue más votada. Bueno, después de crear la sesión hash, en otras páginas que requieren iniciar sesión, necesito verificar $ _SESSION ['logged_in'] o $ _SESSION ['hash']? ¿Entiendes lo que quiero decir? por ejemplo, si (isset ($ _ SESSION ['XXX']) {// do watever} – bbtang

+0

User agent? $ _SESSION ['hash'] = md5 ($ YOUR_SALT. $ username.Firefox); ???? – bbtang

+0

Depende de cómo cerrar la sesión del usuario. Por derecho, debe desactivar la sesión completa. Debe comprobar tanto para logged_in y el hash, en mi humilde opinión. – Extrakun

0

Ésta es la habitual para acceder al sistema de código, algunas mejoras se pueden hacer a hacer que sea más difícil de romper. En primer lugar, se puede hacer una suma de comprobación con el nombre de usuario y la hora de la conexión en o, alternativamente, una cadena predefinida (o una sal), y almacenarlo en la sesión, y compararlo.

Así, cuando el usuario se conecte:

// not the most secure hash! 
$_SESSION['checksum'] = md5($_SESSION['username'].$salt); 

Y antes de entrar en un área sensible:

if (md5($_SESSION['username'].$salt) != $_SESSION['checksum']) 
{ 
    handleSessionError(); 
} 

De manera predeterminada, las sesiones se suelen almacenar como archivos en el servidor, y una galleta es ponga en el navegador del usuario para recordar a qué archivo hacer referencia. Cuando se trata de la sesión de la piratería, de alguna manera el hacker recuperar la información suficiente para duplicar el registro de entrada o las arregló para cambiar los datos de la sesión, utilizando información de la cookie.

podría codificar su propia sesión de manejo de bases de datos utilizando para mayor seguridad. Algunos CMS más estrictos, como Joomla, también registran la IP.Sin embargo, esto causa problemas a las personas que usan cierto ISP

+0

Parece que su método es muy bien, y puedo entender de inmediato. Pero me pregunto por qué nadie vota esta respuesta? Es extraño el método de extrakun? – bbtang

+0

No, está completamente bien. +1 por mencionar la inseguridad de md5 hashs –

1

Puede almacenar la dirección IP, la firma del navegador, etc. para identificar al usuario. En cada solicitud, compruébela con los valores actuales para ver si sucedió algo sospechoso.

Tenga en cuenta que algunas personas están detrás de los proveedores que usan direcciones IP absolutamente dinámicas, por lo que esas personas pueden salir frecuentemente.

+0

Yo mismo, usando dynamic IP, creo que es un poco problemático y podría molestar a los usuarios de IP dinámico ... ¿Tienes una mejor manera? ¿Qué tal el método extrakun? ¿Es bueno? – bbtang

1

Supongo que el segundo tiene que ser 'logged_in'?

Algunos recursos en relación con la seguridad de sesión:

phpsec

shiflett

+0

Basado en el enlace que proporcionaste, después del inicio de sesión del usuario, debería llamar a esto: session_regenerate_id() ? es th ¿en absoluto? Acabo de establecer esta session_regenerate_id() y $ _SESSION ['logged_in'], por lo que en otras páginas que requieren iniciar sesión, simplemente lo hago: if (isset ($ _ SESSION ['XXX']) {// do watever} – bbtang

+0

session_regenerate_id() es una forma de manejar el secuestro de sesión. Pero también tiene desventajas (por ejemplo, el botón de retroceso del navegador no funcionará como se esperaba). Si no tiene un sitio web con datos altamente confidenciales, le aconsejo que regenere solo la identificación de la sesión cuando el usuario hace cosas especiales como cambiar la contraseña, editar su cuenta, o ingresa al área donde hace esas cosas. – koen

+0

@koen: ¿puede explicar lo que quiere decir con "el botón Atrás del navegador no funcionará como se esperaba" ? Después de ver este comentario, investigué un poco, y había otro usuario en este sitio que dijo algo similar, pero que parecía haber sido desacreditado: http://stackoverflow.com/questions/2490707/what-are-the- debilidades de este método de autenticación de usuario/2490749 # 2490749 – Kristina

13

Esto es ridículo.

secuestro de sesión se produce cuando (por lo general a través de un sitio de ataque de secuencias de comandos entre) alguien intercepta su sessionId (que es una cookie enviado automáticamente al servidor web mediante un navegador).

Alguien ha publicado esto, por ejemplo:

Así, cuando el usuario se conecte:

// no el hash más segura! $ _SESSION ['checksum'] = md5 ($ _ SESSION ['username']. $ Sal);

Y antes de entrar en un área sensible:

si (.! Md5 ($ _ SESSION [ 'username'] $ sal) = $ _SESSION [ 'checksum']) {
handleSessionError(); }

Deja para ir a través de lo que está mal en este

  1. Sales - No es malo, pero sin sentido. Nadie está rompiendo su maldito md5, a quién le importa si está salado
  2. comparando el md5 de una variable SESSION con el md5 de la misma variable almacenada en la SESIÓN - está comparando sesión con sesión. Si la cosa es secuestrada, esto no hará nada.
$_SESSION['logged_in'] = 1; 
$_SESSION['username'] = $username; // user's name 
$_SESSION['hash']  = md5($YOUR_SALT.$username.$_SERVER['HTTP_USER_AGENT']); 
nombre

// del usuario, ordenadas por evitar la manipulación

evitar la manipulación por quién? faeries de sesiones mágicas? Sus variables de sesión no se modificarán a menos que su servidor esté en peligro. El hash solo está realmente allí para condensar muy bien tu cadena en una cadena de 48 caracteres (los agentes de usuario pueden ser un poco largos).

Sin embargo, ahora estamos verificando algunos datos de clientes en lugar de verificar los datos de SESIÓN a SESIÓN, han verificado HTTP_USER_AGENT (que es una cadena que identifica el navegador), esto probablemente será más que suficiente para protegerlo, pero tienes que darte cuenta si la persona ya ha tomado tu sessionId de alguna manera, es probable que también hayas enviado una solicitud al servidor de tipos malos y le hayas dado al chico malo tu agente de usuario, para que un hacker inteligente engañe a tu agente de usuario y venza esto proteccion.

¿De qué se trata al llegar a la triste realidad?

Tan pronto como su ID de sesión se vea comprometida, ya no está. Puede verificar la dirección remota de la solicitud y asegurarse de que no cambie en todas las solicitudes (como hice) y eso funcionará perfectamente para el 99% de su base de clientes. Entonces, un día recibirás una llamada de un usuario que utiliza una red con servidores proxy de carga equilibrada, las solicitudes saldrán de aquí a través de un grupo de direcciones IP diferentes (a veces incluso en la red incorrecta) y él perderá su sesión a la derecha y al centro.

+5

definitivamente la mejor respuesta. la información hash dentro de la sesión no ayuda en nada. otro enfoque es almacenar el hash en una cookie separada, de esta manera los chicos malos también tienen que falsificar la cookie – knittl

+0

¿Puede darme algún código? Soy estúpido, puedo leer el código php pero no puedo leer el texto largo, o al menos no entiendo lo que quieres decir. Todo lo que sé es que estás completamente en desacuerdo con el método de otras personas, ya que usaron sal sin sentido. De acuerdo, cuando un usuario inició sesión, ¿qué sesión almacenará? ¿Y qué sesión validará antes de ingresar al área sensible? – bbtang

+1

Otra idea en lugar de verificar la dirección remota es verificar el agente de usuario. No seré tan efectivo como ips (aproximadamente 45% de efectividad) pero no causaré problemas con los usuarios con proxies de carga balanceada. –

1

Para evitar la fijación de sesión, que básicamente consiste en adivinar el SID o robarlo utilizando varios métodos. No importa cuán sofisticada sea la lógica de su sesión, definitivamente será vulnerable al robo sessid hasta cierto punto. Es por eso que debe regenerar la ID cada vez que hace algo importante. Por ejemplo, si va a hacer una publicación o cambiar una configuración en el administrador, primero ejecute session-regenerate-id. Entonces el hacker tiene que pasar por el proceso de hackearlo de nuevo. Esto básicamente le da al pirata informático una oportunidad única con una identificación con todo el tiempo que perdió.

http://us.php.net/manual/en/function.session-regenerate-id.php

O puede cambiar el id de vez resulta

if ($ _ SESSION [ 'contador'] == 3) {session_regenerate_id(); $ _ SESSION [ 'contador'] == 0 }

Además, $ _SERVER ['HTTP_USER_AGENT'] no es muy confiable. Trate de evitarlo no solo por esa razón, sino porque es conveniente para los piratas informáticos porque saben que los agentes son ampliamente utilizados para esto. En su lugar, intente usar $ _SESSION ['id_token'] = sha1 (alguna información loca como memoria de archivos, nombre de archivo, tiempo).

+0

U obtuve un punto (votado), los hackers podrían adivinar fácilmente qué usuario-agente se está usando.Entonces, ¿qué hay de hacer cheque múltiple? Haga una pausa en una sesión, compare la IP con la sesión de IP y compare el agente de usuario con la sesión de agente de usuario. Por cierto, mencionaste que necesito regenerar ID cada vez que hago algo importante, eso significa que necesito destruir cada sesión antes de regenerar una nueva. – bbtang

+0

No necesariamente, siempre y cuando regenere la ID, el hax tendrá que comenzar de nuevo, a menos que tenga acceso al sistema de archivos, en cuyo caso ¡puede modificar el script él mismo! –

0

Cuando me encontré con este problema mientras construía SugarCRM, rastreé y validé la dirección IP del usuario (además de algunas otras cosas). Solo comparé las primeras tres secciones de la dirección IP. Esto permitió la mayoría de las direcciones IP variables locales. También hice posible desactivar la validación de la dirección IP para instalaciones donde una variación importante en la dirección IP era común. Creo que solo comparar el comienzo de la dirección IP te ayuda con la seguridad sin agregar una limitación tan severa a tu aplicación.

Ejemplo: "### ### ### .---.". Sólo la parte de la dirección IP marcada con '#' se verificaría.

192.168.1.101
192.168.1.102
192.168.1.XXX

Todos son considerados iguales.

Jacob

+0

La mayoría de las configuraciones del equilibrador de carga que sé utilizan varios ISP. No puedes confiar en eso. –

+0

Lo que he encontrado es que en condiciones normales, muchos clientes están bien atendidos con este enfoque. Si tienen una configuración de administración de red muy agresiva, es posible que necesiten desactivarla. Fue fácil desactivar la verificación. Muchos clientes solo tendrían un cambio importante cuando se modifique o rompa una tubería de red. – TheJacobTaylor

Cuestiones relacionadas