Foros del Web » Programando para Internet » PHP »

Echen un ojo a este autentificador.

Estas en el tema de Echen un ojo a este autentificador. en el foro de PHP en Foros del Web. Hola amigos, Hice un autentificador casi al vuelo, pero me gustaría que le echen un vistaso y me digan de que manera podrían violar la ...
  #1 (permalink)  
Antiguo 13/10/2008, 22:07
Avatar de Celcius  
Fecha de Ingreso: febrero-2003
Ubicación: Lima - Perú
Mensajes: 652
Antigüedad: 21 años, 2 meses
Puntos: 5
Echen un ojo a este autentificador.

Hola amigos,
Hice un autentificador casi al vuelo, pero me gustaría que le echen un vistaso y me digan de que manera podrían violar la seguridad del mismo.

http://goldfarb.110mb.com/autenticacion.tar.gz

Tambien lo pongo para que el que desee lo pueda estudiar. Solo mencionar que debe crearse una base de datos en mysql de nombre "prueba", una tabla de nombre usuarios y los campos son los siguientes:
id, usuario, contra, nivel

El nivel puede ser 0 o 1.

Eso seria todo, espero sus comentarios.

un saludo
__________________
"Si tú conocieras el don de Dios, y quién es el que te dice: 'Dame de beber,' tú Le habrías pedido a El, y El te hubiera dado agua viva.
Sn. Juan 4:19
Jesus
  #2 (permalink)  
Antiguo 13/10/2008, 22:27
Avatar de Ronruby  
Fecha de Ingreso: julio-2008
Ubicación: 18°30'N, 69°59'W
Mensajes: 4.879
Antigüedad: 15 años, 9 meses
Puntos: 416
Respuesta: Echen un ojo a este autentificador.

Postea el codigo aqui mismo en el foro. De lo contrario no muchos podran echarle un ojo.

Cita:
me digan de que manera podrían violar la seguridad del mismo.
Acabo de echarle un vistazo ...
De que forma pueden violar la seguridad del mismo? ... Infinitas.

No validas los campos, tu script es vulnerable a XSS (Cross Site Scripting) y SQL Injection ...
Es super facil loguearse como cualquier usuario solo sabiendo su username.
Yo digo que demasiado simple.

Tampoco se para que cuando redireccionas a la pagina de login lo haces poniendo un querystring si ocurre un error y en tu script donde esta el formulario no recojes la querystring.
Guardas el usuario y la contraseña en una SESSION, cuando con el ID es mas que suficiente. Para que necesitas el Password en una session luego de haber logueado al usuario?

Última edición por Ronruby; 13/10/2008 a las 23:36
  #3 (permalink)  
Antiguo 14/10/2008, 05:24
 
Fecha de Ingreso: abril-2008
Mensajes: 453
Antigüedad: 16 años, 1 mes
Puntos: 16
Respuesta: Echen un ojo a este autentificador.

Tiene razon Ronruby, no es necesario guardar tantos datos, la verdad es muy inseguro, con el numero de ID es suficiente con el mismo podes recoger el dato que necesites cuando lo necesites, en mi caso tengo una clase usuarios y pasando el id obtengo el dato que necesito en ese momento de ese usuario, la contraseña la compruebo en el login y si todo esta bien ahi asigno la id a la session
  #4 (permalink)  
Antiguo 14/10/2008, 05:28
Avatar de Celcius  
Fecha de Ingreso: febrero-2003
Ubicación: Lima - Perú
Mensajes: 652
Antigüedad: 21 años, 2 meses
Puntos: 5
Respuesta: Echen un ojo a este autentificador.

Jejeje excelente!!! Tus consejos observaciones me sirven de mucho, voy a averiguar todo eso para poder implementarlo... Bueno aqui está el código:

puerta.php
Código PHP:
<?php
session_start
();
error_reporting(E_ALL);
$_SESSION["inicio"]="desde_la_puerta";
?>

<FORM action="comprueba.php" method="POST">
<table border="0" cellspacing="0" cellpadding="0" width="300" align="center">
<TR>
    <TD>Usuario</TD>
    <TD>: <input type="text" name="usuario"></TD>
</TR>
<TR>
    <TD>Contrase&ntilde;a</TD>
    <TD>: <input type="password" name="contrasena"></TD>
</TR>
<TR>
    <TD colspan="2"><input type="submit" value="Enviar"></TD>
</TR>
</table>
</FORM>
comprueba.php
Código PHP:
<?php
session_start
();
error_reporting(E_ALL);
if(
$_SESSION["inicio"]=="desde_la_puerta"){
    
$usuario $_POST["usuario"];
    
$contra $_POST["contrasena"];
    
mysql_connect("localhost","root","41234160");
    
mysql_select_db("prueba");
    
$consulta mysql_query("
    SELECT *
    FROM usuarios WHERE usuario='$usuario' and contra='$contra'
    "
)or die("Error");
    if(
mysql_num_rows($consulta)>0){
    
$datos mysql_fetch_assoc($consulta);
    
$_SESSION["usuario"]["nivel"]=$datos["nivel"];
    
$_SESSION["usuario"]["usuario"]=$datos["usuario"];
    
$_SESSION["usuario"]["contrasena"]=$datos["contra"];
    
$_SESSION["usuario"]["logeado"]="si";
    
header("location: repartir.php");
    exit;
    }else{
    
header("location: puerta.php?error=si");
    exit;
    }
}else{
    
header("location: puerta.php?error=si");
    exit;
}

?>
repartir.php
Código PHP:
<?php
session_start
();
error_reporting(E_ALL);
if(isset(
$_SESSION["usuario"]["logeado"]) && isset($_SESSION["inicio"]) && $_SESSION["inicio"]=="desde_la_puerta"){
    switch (
$_SESSION["usuario"]["nivel"]){
        case 
0:
            
header("location: intranet/admin.php");
            exit;
        case 
1:
            
header("location: intranet/profesor.php");
            exit;
    }
    
}else{
    
header("location: puerta.php?error=no_correcto");
    exit;
}

?>
admin.php (debe estar dentro de una subcarpeta llamada "intranet")
Código PHP:
<?php
session_start
();
error_reporting(E_ALL);
$nivel="0";
//por si no existen las variables de sesión.
if(!isset($_SESSION["inicio"]) || !isset($_SESSION["usuario"]["nivel"]) || !isset($_SESSION["usuario"]["logeado"])){
header("location: ../puerta.php?error=acceso_equivocado");
exit;
}
//por si se intenta acceder desde otro lugar que no sea la puerta de nuestro sistema.
if($_SESSION["inicio"]!="desde_la_puerta" || $_SESSION["usuario"]["nivel"]!=$nivel || $_SESSION["usuario"]["logeado"]!="si"){
header("location: ../puerta.php?error=error_de_acceso");
exit;
}
echo 
"Bienvenido a la seccion del admin";

?>
profesor.php (guardar igual que admin)
Código PHP:
<?php
session_start
();
error_reporting(E_ALL);
$nivel="1";
if(!isset(
$_SESSION["inicio"]) || !isset($_SESSION["usuario"]["nivel"]) || !isset($_SESSION["usuario"]["logeado"])){
header("location: ../puerta.php?error=acceso_equivocado");
exit;
}
if(
$_SESSION["inicio"]!="desde_la_puerta" || $_SESSION["usuario"]["nivel"]!=$nivel || $_SESSION["usuario"]["logeado"]!="si"){
header("location: ../puerta.php?error=logearse_de_nuevo");
exit;
}
echo 
"Bienvenido a la seccion del profesor";

?>
destruir.php (no hay ningún enlace hacia éste archivo, ingreso directamente desde la barra de direcciones para poder destruir las sesiones)
Código PHP:
<?php
error_reporting
(E_ALL);
session_start();
session_destroy();
header("location: puerta.php");
exit;
?>
Podrías decirme (en forma de ayuda) cómo harías tu para hacerlo mas seguro? osea, como protegerlo contra XSS, SQL Inyection? Bueno debo confesar que lo hice en casi una hora de trabajo, claro que no justifica las vulnerabilidades que no sé corregir (por ahora )

Cita:
Yo digo que demasiado simple
Estoy de acuerdo contigo, echen todo lo malo que vean, mientras mas hayan, mejor.. un abrazo y muchas gracias por sus sugerencias.
__________________
"Si tú conocieras el don de Dios, y quién es el que te dice: 'Dame de beber,' tú Le habrías pedido a El, y El te hubiera dado agua viva.
Sn. Juan 4:19
Jesus

Última edición por Celcius; 14/10/2008 a las 05:34
  #5 (permalink)  
Antiguo 14/10/2008, 05:46
 
Fecha de Ingreso: mayo-2004
Ubicación: Argentina
Mensajes: 126
Antigüedad: 20 años
Puntos: 1
Respuesta: Echen un ojo a este autentificador.

Se viene el Autentificator 2 !!!??? (El de Cluster tenia un temilla de seguridad si mal no recuerdo...)
  #6 (permalink)  
Antiguo 14/10/2008, 06:32
 
Fecha de Ingreso: abril-2008
Mensajes: 453
Antigüedad: 16 años, 1 mes
Puntos: 16
Respuesta: Echen un ojo a este autentificador.

mira te muesto como lo hago con la clase que hice capaz que les sirva:

Código PHP:

<?php

class usuario {
        public 
$id;
        public 
$login;
        public 
$tipo ;
        public 
$permiso;
        public 
$email;
        public 
$valor;
    
    
    public function 
setUser($Euser,$Epass){
        
$com self::checkUser($Euser,$Epass);
        
                
            if(
$com==TRUE){
                
$data self::GetUserInfo();
                
$this->id $data[0];
                
$this->login $data[1];
                
$this->tipo $data[3];
                
$this->permiso $data[4];
                
$this->email $data[5];
                
$valor DbConn::GetAllArr('permisos');
                
$this->valor $valor[$data[4]][2];
                
                
                
$_SESSION['id'] = $data[0];    
                
                
            }else{
                
$this->login false;
                echo 
'los datos no coinciden';
            }
            
    }
    
    
    
    
    private function 
checkUser($Euser,$Epass){
        global 
$DbConn;
            
$sql "Select * From usuarios WHERE login='$Euser'";
            
$res $DbConn->query($sql);
            
$data $DbConn->fetchArray($res);
            
            
            if(
$data['pass']==$Epass){
                
$this->login $Euser;
                return 
true;
                
            }else{
                return 
false;
            }
        
    }

    public function 
GetUserInfo($id=''){
        global 
$DbConn;
            if(
$id==''){
            
$usuario =  $this->login;
            
$sql "Select * From usuarios WHERE login='$usuario'";
            
$res $DbConn->query($sql);
            
$data $DbConn->fetchArray($res);
            
            }else{
            
$sql "Select * From usuarios WHERE idUsuario='$id'";
            
$res $DbConn->query($sql);
            
$data $DbConn->fetchArray($res);
            }
            
            
            
            return 
$data;
    }
compruebo los datos con una funcion de la clase si los datos son correctos guardo la id de session, fijate que tengo otra funcion que es GetUserInfo que con la ID puedo obtener el dato que necesito sin tener que guardar ninguna otra cosa entonces si quiero saber el nombre del usuario actual seria cuestion de hacer
Código PHP:
 $datos $usActual->GetUserInfo($_SESSION['id']);
 
$login $datos['login']; 
teniendo la clase cuando proceso el formulario pongo lo siguiente:
Código PHP:
if($_POST['check']=='ok'){
    
    
$usActual->setUser($_POST['usuario'],$_POST['pass']);
    
redirect($_SERVER['HTTP_REFERER']);


donde redirect es una funcion personalizada para no usar header location, ya que a veces necesito redireccionar a la misma pagina, te dejo tambien el codigo de la funcion por si te interesa

Código PHP:
function redirect($pagina){
        echo 
            
'<script type="text/javascript">
            window.location="'
.$pagina.'";
            </script>'
;
    } 
es simple pero efectivo

Última edición por samu22; 14/10/2008 a las 06:36 Razón: faltaba mas info
  #7 (permalink)  
Antiguo 14/10/2008, 10:47
Avatar de Ronruby  
Fecha de Ingreso: julio-2008
Ubicación: 18°30'N, 69°59'W
Mensajes: 4.879
Antigüedad: 15 años, 9 meses
Puntos: 416
Respuesta: Echen un ojo a este autentificador.

Cita:
Podrías decirme (en forma de ayuda) cómo harías tu para hacerlo mas seguro? osea, como protegerlo contra XSS, SQL Inyection? Bueno debo confesar que lo hice en casi una hora de trabajo, claro que no justifica las vulnerabilidades que no sé corregir (por ahora)
Usa mysql_real_escape_string() para evitar SQL Injection, valida los datos usando expresiones regulares para solamente permitir caracteres alfanumericos, guiones y unos cuantos mas.
Nunca puedes confiar en los datos que el usuario introducira.
Unos cuantos IF bastaran para solucionarlo y otras funciones mas puedes solucionarlo. addslashes(), trim(), stripslashes(), htmlentities(), etc...

Usa algun algoritmo de Hash para encriptar las contraseñas al guardarlas en la base de datos como md5 o sha1.

Y ya que cuando sucede un error redireccionas a la pagina de login, seria bueno que recojas el querystring que envias y dependiendo de este, mostrar un mensaje de error. Asi el usuario esta al tanto de que sucede.
  #8 (permalink)  
Antiguo 25/10/2008, 21:21
Avatar de Celcius  
Fecha de Ingreso: febrero-2003
Ubicación: Lima - Perú
Mensajes: 652
Antigüedad: 21 años, 2 meses
Puntos: 5
Respuesta: Echen un ojo a este autentificador.

Hola, bueno estuve revisando los temas de Expresiones regulares (pues es un tema que antes escuché, pero que ahora me decidí a aprender) y estoy en eso, en el aprendizaje. Te pediría que me des tu sincera opinión sobre éste código para validar usuario y contraseña, específicamente los patrones para el usuario y el password.

Código PHP:
<?php
$user 
="admin";
$pass="holaMundo007";
$patronuser="^admin$";
$patronpass "^([a-zA-Z 0-9_]{5,15})$";
//comprobamos que el usuario sea correcto
if(ereg($patronuser,$user)){
    if(
ereg($patronpass,$pass)){
            echo 
"Usuario y password correctos";
        }else{
            echo 
"Quien eres!!";
        }
}else{
    
$patronuser="^(PRF|ALU)[0-9]{2,3}$";
    if(
ereg($patronuser,$user)){
        if(
ereg($patronpass,$pass)){
            echo 
"Usuario y password correctos";
        }else{
            echo 
"Quien eres!!";
        }
    
    }else{
        echo 
"Oh no, quien eres?";
    }
}
?>
Aunque no lo creas me fue dificil asimilar éste concepto y con el trabajo tuve que tomarme un tiempecito.. asi es que si me lo apruebas (:D) paso a aprender lo demás que me parece MUCHO más facil que éstas benditas expresiones regulares (pero que buenas!)

Alguna sugerencia adicional al código??? gracias!

saludos,
__________________
"Si tú conocieras el don de Dios, y quién es el que te dice: 'Dame de beber,' tú Le habrías pedido a El, y El te hubiera dado agua viva.
Sn. Juan 4:19
Jesus
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:52.