Ola, somos Arume

Desenvolvemos páxinas web, aplicacións para móbiles, capas de realidade aumentada e aplicacións para Facebook. Apaixónanos a informática e somos uns perfeccionistas incurables; por eso nos nosos proxectos utilizamos estándares.

tel. 625 519 694

Mendaña de Neyra, 34, 3º B, 15008, A Coruña

Autenticarse

Rexistrarse. Esqueceches o teu contrasinal?

Etiquetas

Saltar as etiquetas

Subscríbete ás RSS

Estás en:

  • Inicio >
  • Blog >
  • Seguridade das sesións en PHP: Session Fixation

Seguridade das sesións en PHP: Session Fixation

23 Dec 2010 por Luis

Comentarios: 5

Fixación de sesión

Session fixation (fixación de sesión) é un método de Session hijacking (roubo de sesión) un pouco especial, xa que, se normalmente no roubo de sesión inténtase conseguir o identificador de sesión dun usuario xa *autenticado, a fixación de sesión baséase en asignar un identificador de sesión coñecido a un usuario antes de que se autentique.

Por facer unha analoxía: o roubo de sesión é como intentar roubar a clave dunha tarxeta de crédito, mentres que a fixación de sesión é intentar que a vítima cambie a súa clave a un número dado (e polo tanto coñecido) polo atacante.

O malo deste ataque é que é moi fácil de realizar. O bo, é que é moi fácil de previr.

Como se realiza o ataque

Como podemos ler no artigo sobre o funcionamento das sesións, hai varias formas de propagalas entre páxinas dun mesmo sitio web. Unha delas, a URL, é a máis fácil de atacar.

Supoñamos que a páxina web atacada utiliza o nome de sesión por defecto en PHP: PHPSESSID. O atacante só ten que crear unha ligazón á páxina web obxectivo desta forma:

http://www.web-atacada.com/?PHPSESSID=123456

Despois, só ten que facer que o usuario ó que quere atacar utilice esa ligazón para acceder á páxina web. Isto pódese conseguir de varias formas: enviándolle a ligazón por email, a través dunha rede social ou, incluso, sen que o usuario se dea conta, facendo unha redirección desde unha páxina web do atacante.

Unha vez que o usuario utiliza esta ligazón, estalle dicindo á páxina web que o seu identificador de sesión é 123456. PHP ó comprobar que non existe unha sesión con ese identificador, créaa e asígnalla ó usuario. Se este se autentica no sitio, o atacante, que coñece o seu identificador de sesión (123456), pode facerse coa súa conta facéndose pasar por el.

Atención: aínda que a páxina web utilice cookies para a propagación do identificador de sesión, normalmente a configuración de PHP acepta o identificador na URL (despois propágao a través de cookies pero cando xa creou a sesión con ese identificador). Tamén hai que ter en conta que un atacante pode (con técnicas moito máis avanzadas e aproveitando erros nas directivas de seguridade dos navegadores) realizar este ataque inserindo unha cookie ó usuario. Aínda que é a forma máis sinxela, este ataque non se limita só á propagación por URL.

Métodos de prevención

Se ben é un ataque que se pode realizar facilmente, a prevención é igualmente fácil. Podemos tomar as seguintes medidas:

  • Utilizar unicamente cookies para a propagación do identificador de sesión. Esta medida non anula o perigo, pero fai máis difícil o ataque (e moitos outros). En PHP conséguese así:

    ini_set('session.use_only_cookies', 1);
  • Rexenerar os *identificadores de sesión para sesións novas. Isto conséguese pondo unha "marca" nas sesións da páxina web. Cada vez que se fai un session_start(), se a sesión non ten a "marca", cambiamos o seu identificador por un novo (session_regenerate_id(true);) e descoñecido para o atacante. Exemplo:

    session_start();
    
    if (isset($_SESSION['mark']) === false)
    {
    	session_regenerate_id(true);
    	$_SESSION['mark'] = true;
    }
  • Cambiar o identificador de sesión sempre que un usuario cambie o seu estado (autenticado, rexistrado, ...). Ca anterior medida de protección pode parecer que xa estamos protexidos, pero un atacante pode entrar na páxina web, xerar unha sesión con "marca" e despois mandar o identificador desa sesión ó usuario atacado. Así o usuario atacado acabaría cunha sesión con "marca" e coñecida polo atacante. Por iso, débese rexenerar o identificar de sesión sempre que un usuario realice unha acción que lle obrigue a autenticarse. Exemplo:

    if ($user_logged_in === true)
    {
    	session_regenerate_id(true);
    	$_SESSION['logged'] = true;
    }

Aviso: é moi importante que sexa session_regenerate_id(true); e non session_regenerate_id(); xa que se non eliminamos a sesión antiga, estamos facendo máis fácil os ataques contra a páxina web ao deixar múltiples sesións válidas abertas no servidor.

No próximo e definitivo artigo sobre vulnerabilidades das sesións, un último tipo de ataque e a súa prevención.

Comentarios

5 comentarios. Comentar.

1. Eldev o 08 Mar 2011 ás 05:06:00

muy bueno y util su aporte, sigan asi :).

Consejo: Aumenten el tamaño de las letras del texto y que el color del mismo contraste mas con el fondo ;)

2. Pedro o 14 Abr 2011 ás 07:04:50

muchas gracias por el pequeño tutorial es de mucha utilidad

3. Josue Sanchez o 12 Feb 2016 ás 16:23:25

Hola,

Una duda que me genera al ver este buen tutorial es... como debo cerrar después la session?

4. Caimán o 28 Set 2016 ás 22:20:19

Buenas, quiero felicitarte por la claridad de las explicaciones en general.

Tengo una duda con respecto a la regeneración del id de sesión.

Si el server tiene los siguientes registros:

Cliente A con PHPSESSID = 12345

Cliente B con PHPSESSID = 78945

Cada vez que el cliente A realice una acción, a este se le regenerará el PHPSESSID. Supongamos que este realizó una acción y se le regeneró su PHPSESSID a "55555".

Si el Cliente B utiliza el PHPSESSID = 55555, entonces ingresaría como el Cliente A y se le regeneraría su PHPSESSID nuevamente y no serviría de nada... Como funciona esto?

5. Luis o 30 Set 2016 ás 12:02:24

Hola Caimán.

El servidor se encarga de que no se genere un PHPSESSID que ya está siendo usado.

De todas formas, aunque yo he puesto aquí identificadores como los que tú indicas, lo he hecho sólo para que se entendiese la explicación. En realidad, los PHPSESSID son (por defecto) así: 31d7bgphebfemb55311b1cger6. La probabilidad de que se repita un identificador de sesión es muy baja (si fuese fácil que se repitiesen, sería muy fácil atacar un sistema utilizando identificadores de sesión al azar).

Un saludo.

Comentar

Comentar de forma anónima

Podes comentar poñendo calquera nome ou alcume, exceptuando os nomes de usuarios rexistrados. Máximo de 50 caracteres.

Comentar como usuario rexistrado

Rexistrarse. Esqueceches o teu contrasinal?