Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > PHP
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-03-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
A ver, no quiero quitar el dedo del renglón.

El problema para usar sesiones es que herramientas como Snoopy no tienen manera de guardar las cookies que reciben, incluida la PHPSESSID de sesión, y por tanto, en cada petición, el servidor piensa que es la primera y genera una nueva sesión.

Ahora bien, ésta no es la situación de un usuario normal, y si alguien quiere usar Snoopy para algún fin lícito, tendrá que preocuparse por como preservar esa cookie y enviarla al servidor.

Entonces, el problema está con los chicos malos que intentarán confundir al servidor explotando esta particularidad.

Siendo así, ¿por qué no aprovechar esta amnesia de sesión para detectar si alguien no está jugando limpio?

La idea es generar un valor aleatorio o token al momento de presentar el formulario de login. Este valor se guarda en la sesión y se manda junto con el formulario como un campo hidden. El script que recibe los datos del formulario, verifica que exista dicho campo oculto y que su valor coincida con el que tiene guardado en la sesión.

Esto, de entrada, impide usar Snoopy para invocar directamente al script que procesa el formulario -los datos tiene que enviarse forzosamente desde el formulario que presentamos nosotros mismos. Snoopy podría "leer" ese formulario, usar el DOM para leer el campo oculto y enviarlo junto con la petición al script procesador. Esto es lo que haría alguien que quiere utilizar Snoopy u otra herramienta similar con un fin genuino. Pero si no es así, entonces la sesión no se preservará y el script que recibe los datos del formulario no reconocerá el campo escondido pues no lo tendrá guardado en la sesión, y, de esta manera, sabrá que se trata de una petición no válida.

En resumen, que les damos una cucharada de su propia medicina.

¿Cómo ven?

Claro que esto no invalida la opción de usar la base de datos, pero es una alternativa que, de hecho, se usa con frecuencia para dar mayor seguridad a nuestros formularios de login (buscar forms+tokens en google).

// Saludos
Responder Con Cita
  #2  
Antiguo 11-03-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Hola,

Creo que me enredé demasiado con los tokens.

Basta guardar una variable de sesión cualquiera en la página que muestra el formulario y preguntar por ella en el script que procesa el formulario.

Si no existe la variable, consideramos inválida la petición y abortamos. El atacante podrá hacerlo cuantas veces quiera que siempre obtendrá la misma respuesta: "petición no válida".

La única forma que tiene para no obtener dicha respuesta es preservando la sesión, y una vez hecho esto ya lo tenemos amarrado y podemos contar los intentos con una variable de sesión, que, de hecho, puede ser la misma que la otra:

login-form.php
Código PHP:
<?php
session_start
();
$_SESSION['intentos'] = 0;
?>
<form method='post' action='login.php'>
    <div>
        <label for='user'>User</label>
        <input type='text' name='user' id='user'>
    </div>

    <div>
        <label for='password'>Pwd</label>
        <input type='text' name='password' id='password'>
    </div>

    <div>
        <input type='submit'>
    </div>
</form>

login.php
Código PHP:
<?php
session_start
();

if (!isset(
$_SESSION['intentos']))
{
  die(
'Petición no válida');
}

/*
  Verificamos los datos de inicio
*/

...

/*
  Si son incorrectos, marcamos un intento más
*/

$_SESSION['intentos']++;

/*
  Y lo mandamos a volar si ya rebasó el máximo permitido
*/
if ($_SESSION['intentos'] > 3)
{
  die(
'Demasiados intentos');
}
?>
// Saludos
Responder Con Cita
  #3  
Antiguo 12-03-2009
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Antes de nada, te agradezco el interés Román, doblemente, por la posible solución. Digo posible, porque, aunque todavía no lo he probado tal como dices, me entran dudas sobre el uso de las sesiones, puesto que es lo que había intentado anteriormente. ¿No se supone que las variables de sesión son únicas para cada sesión? Pero, si el "script" cambia dicha variable de sesión... ¿no estamos como al principio? Pero, igual es que no he leído bien tus mensajes Román.

Echaré un vistazo, haré las pruebas oportunas, y comentaré aquí los resultados. Gracias de nuevo Román.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #4  
Antiguo 12-03-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por dec Ver Mensaje
Pero, si el "script" cambia dicha variable de sesión... ¿no estamos como al principio?
No podemos evitar que nos cambien la sesión. El punto aquí es que si lo hacen, nosotros lo detectamos y los mandamos a volar. Dicho de otra forma, la única manera de que puedan autenticarse en nuestro sistema es no cambiando la sesión, con lo cual tenemos un ambiente controlado.

Olvídate un poco de los tokens (son útiles pero no se requiere tanto) y fíjate en el ejemplo que puse:

1. Es imposible llamar directamente a login.php pues no habrá ninguna sesión y por tanto ninguna variable $_SESSION['intentos']

2. Esta variable se establece en login-form.php

3. Si en el paso de login-form.php a login.php cambia el ID de sesión, entonces login.php ya no reconocerá la variable intentos.

1 y 3 vienen a ser lo mismo. El caso es que ni siquiera se llega a verificar usuario y contraseña, y por tanto el atacante no tiene forma de decidir si eran datos correctos o no.

// Saludos
Responder Con Cita
  #5  
Antiguo 12-03-2009
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Bueno. Ahora mismo lo que más me llama la atención, es que, en el caso de Gesbit, existe un "user-login.php", donde se realiza la autenticación. No hay dos "scripts", sino uno solamente. Pero, perdona que insista Román (porque igual lo de los "tokens" resulte más conveniente), precisamente, porque no contamos con una sesión "estable", es que no podemos basarnos en ella para este caso.

1º Establezco la variable de sesión "contador"

2º Reviso si existe la variable contador (para incrementarla, si es preciso) ¡Error!

No existe la variable "contador"... no se ha establecido para la sesión "actual"... porque el "script" (Snoopy) siempre juega con una nueva sesión, la variable "contador" ya no existe..., dicho de otro modo, siempre estaríamos estableciendo una variable "contador", pero, no podríamos incrementar esa misma variable contador: de ahí la necesidad de usar una base de datos... para hacer persistir sí o sí esa información, para desligarla de la sesión de usuario.

¿No?
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #6  
Antiguo 12-03-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Por un sólo script, me imagino que te refieres a que el mismo presenta el formulario y el mismo procesa los datos. Pero aún así son dos scripts distintos: el mismo a dos tiempos.

Sería algo así:

user-login.php
Código PHP:
<?php
session_start
();

if (
$_SERVER['REQUEST_METHOD'] == 'POST')
{
    
// Aquí el "segundo" script

    
if (!isset($_SESSION['intentos']))
    {
      die(
'Petición no válida');
    }

    
/*
      Verificamos los datos de inicio
    */

    
...

    
/*
      Si son incorrectos, marcamos un intento más
    */

    
$_SESSION['intentos']++;

    
/*
      Y lo mandamos a volar si ya rebasó el máximo permitido
    */
    
if ($_SESSION['intentos'] > 3)
    {
      die(
'Demasiados intentos');
    }

    exit;
}

$_SESSION['intentos'] = 0;
?>
<form method='post' action='login.php'>
    <div>
        <label for='user'>User</label>
        <input type='text' name='user' id='user'>
    </div>

    <div>
        <label for='password'>Pwd</label>
        <input type='text' name='password' id='password'>
    </div>

    <div>
        <input type='submit'>
    </div>
</form>
Cita:
Empezado por dec
2º Reviso si existe la variable contador (para incrementarla, si es preciso) ¡Error!
¡Exacto! Ése es el punto. Si no existe la variable contador, es un error. No es que haya que volverla a inicializar, es un error y le mandamos el

Código PHP:
die('Petición no válida'); 
La única forma en que no se dé ese error es teniendo definida esa variable de sesión y eso lo hacemos al presentar el formulario. Si el listillo nos cambia la sesión pues el afectado es él porqué recibira el error.

// Saludos
Responder Con Cita
  #7  
Antiguo 12-03-2009
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

A ver, que, quiero cogerle el punto (atentos argentinos queridos, cogerle el punto aquí significa lo que significa, ¡y nada más!).

Cita:
Empezado por Román
La única forma en que no se dé ese error es teniendo definida esa variable de sesión y eso lo hacemos al presentar el formulario. Si el listillo nos cambia la sesión pues el afectado es él porqué recibira el error.
Hum... o sea, tratar de aprovechar, precisamente, que no se puede mantener la sesión en condiciones. Pero, ¿esto cómo lo hacemos? Pongámonos en el caso.

El "script" (Snoopy) enviará, directamente, el formulario. Luego siempre estaremos "como en un principio". Siempre será "la primera vez" que se trata de envíar nuestro formulario. Si establecemos una variable de sesión ahí, de nada nos serviría, porque, no la tendríamos a nuestra disposición la siguiente vez. Pero, no sabríamos si es que es la siguiente vez (después de haberla establecido) o no, porque, como el "script" inicia una sesión nueva cada vez... siempre será como la primera vez (argentinos, que os veo con el cachondeíto).

No termino de verlo claro Román. El "script" (Snoopy) no quiere entrar en nuestro sistema, sólo quiere saber si el formulario se procesa bien o mal, si consigue autenticarse con unos datos de usuario, o no lo consigue. No es posible que mantenga (de hecho, ni querrá hacerlo) una sesión de usuario, luego nosotros no podemos basarnos en sesiones de usuario... simplemente es que no podemos... yo lo ví tan claro (que podía hacerse) que hasta me precipité en implementarlo, pero, en cuanto probé con Snoopy... caí en la cuenta de que no podía basarse algo así en variables de sesión: porque no podemos contar con una sesión de usuario.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Como hacer que se vea "Si" en vez de "TRUE" en un DBGrid lu9eui C++ Builder 2 07-08-2007 04:03:13
Acceso a Outlook 2003 Reminders y error "Invalid Variant Operation" saldanaluis Providers 2 24-05-2007 21:17:58
Implementar una nueva opción para la propiedad "FormStyle" JM75 OOP 3 15-02-2007 15:53:44
Implementar "FloodFill" en CLX salvica Gráficos 1 07-09-2004 19:52:45


La franja horaria es GMT +2. Ahora son las 08:38:57.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi