Foros del Web » Programando para Internet » PHP »

Este codigo evita sql injection?

Estas en el tema de Este codigo evita sql injection? en el foro de PHP en Foros del Web. Hola a todos. Quería preguntaros una duda que me ha surgido. He estado probando y no he podido loguearme usando como contraseña tipicos ataques estilo ...
  #1 (permalink)  
Antiguo 27/01/2012, 14:23
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Este codigo evita sql injection?

Hola a todos.

Quería preguntaros una duda que me ha surgido.
He estado probando y no he podido loguearme usando como contraseña tipicos ataques estilo 'or '1'='1

El código es el siguiente:
NOTA:
$password es una cadena codificada en MD5.
$passwordNoMD5 es una cadena tal cual la recibo del usuario, sin comprobaciones de control ni nada.

Código PHP:
Ver original
  1. $qry = "SELECT password FROM clients WHERE username='$username' AND password='$password' OR password='$passwordNoMD5'";
  2. if ($sql = mysql_query($qry)){
  3.     $client = mysql_fetch_assoc($sql);
  4.     if ($client['password'] == $password || $client['password'] == $passwordNoMD5){
  5.         return true;                   
  6.     }else
  7.         return false;
  8.     }

Existe vulneración alguna?

Gracias de antenamo.
  #2 (permalink)  
Antiguo 27/01/2012, 14:25
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Este codigo evita sql injection?

En tu código no se ve problema, aparentemente.

Todo radica en la forma en que defines las variables que usas en la consulta, como no podemos ver que haces no se puede decir más.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 27/01/2012, 14:29
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Respuesta: Este codigo evita sql injection?

Código PHP:
Ver original
  1. Pongo el codigo completo:
  2.  
  3. public function login($username,$password,$passwordNoMD5){
  4.                
  5.     $qry = "SELECT password FROM clients WHERE username='$username' AND password='$password' OR password='$passwordNoMD5'";
  6.     if ($sql = mysql_query($qry)){
  7.         $client = mysql_fetch_assoc($sql);
  8.         if ($client['password'] == $password || $client['password'] == $passwordNoMD5){
  9.             return true;                   
  10.         }else
  11.             return false;
  12. }  
  13.  
  14.  
  15. login($username,md5($password),$password);
  #4 (permalink)  
Antiguo 27/01/2012, 14:31
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Este codigo evita sql injection?

A eso no me refiero, yo hablo de la manera en que defines tus variables antes de pasarlas a tu función.

Código PHP:
$usuario = ???; 
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #5 (permalink)  
Antiguo 27/01/2012, 14:33
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Respuesta: Este codigo evita sql injection?

$username es una cuenta de correo, por ejemplo:

$username = '[email protected]';
$password = '4234u32niu4n239432dv3';
$passwordNoMD5 = (lo que escriba el usuario);
  #6 (permalink)  
Antiguo 27/01/2012, 14:34
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Respuesta: Este codigo evita sql injection?

$username si que pasa por un control para asegurarme que lo que me envía es una cuenta de correo con el formato ###@####.###
  #7 (permalink)  
Antiguo 27/01/2012, 14:35
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Este codigo evita sql injection?

¿Esa es la forma real en la que asignas los valores?
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #8 (permalink)  
Antiguo 27/01/2012, 14:38
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Respuesta: Este codigo evita sql injection?

Con real te refieres a que si las variables se llenan de ese modo?

En la realidad absoluta, tendría que poner el form con el action a un .php de validación.
Después $username pasa por un control de datos y si cumple con los requisitos, lanzo la peticion
login($username,md5($password),$password);

No pondré todos esos pasos porque el kit de la cuestión es si la consulta no dará ningún error o si existe algún agujero de seguridad
  #9 (permalink)  
Antiguo 27/01/2012, 14:41
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Este codigo evita sql injection?

Bueno, con "real" efectivamente me refiero a la forma real en que ejecutarás dicho script.

Si los datos provienen de un formulario debes validar y escapar todo valor, como regla general, jamás confíes en el usuario.

Te sugiero que busques temas similares en el foro, hay bastantes.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #10 (permalink)  
Antiguo 27/01/2012, 14:48
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Respuesta: Este codigo evita sql injection?

Nunca me fio del usuario.

La variable $username la tengo bien controlado, el usuario no puede colar nada extraño.
La variable $password se convierte en md5, con lo que no hay forma de que se cuele nada.

La duda era en la variable $passwordNoMD5, es el único punto que me "preocupa".
  #11 (permalink)  
Antiguo 27/01/2012, 14:49
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Este codigo evita sql injection?

Pues entonces lo único que estás olvidando es escapar dicha variable.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #12 (permalink)  
Antiguo 27/01/2012, 14:54
 
Fecha de Ingreso: julio-2006
Mensajes: 9
Antigüedad: 17 años, 9 meses
Puntos: 0
Respuesta: Este codigo evita sql injection?

Bueno, yo veo problemas al no limpiar las variables en la consulta porque realmente no sabes los valores que le van a asignar a tus variables, yo siempre limpio mis variables utilizando sprintf el cual me devuelve una cadena formateada de acuerdo al tipo de dato que le estoy especificando por ejemplo si pongo %d estoy pidiendo que me devuelva un entero, si pongo %s estoy pidiendo que me devuelva una cadena, y adicionalmente uso la función mysql_real_escape_string() la cual coloca barras invertidas a los caracteres especiales para que no los tome en cuenta como parte de la consulta por ejemplo el apostrofe '.

Ejemplo:

Código PHP:
Ver original
  1. $strSql=sprintf("DELETE FROM clientes WHERE idcli='%s';",
  2.                 mysql_real_escape_string($id));
  #13 (permalink)  
Antiguo 27/01/2012, 15:27
webankenovi
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Este codigo evita sql injection?

has dicho antes:$passwordNoMD5 es una cadena tal cual la recibo del usuario, sin comprobaciones de control ni nada.
Nunca me fio del usuario.

La variable $username la tengo bien controlado, el usuario no puede colar nada extraño.
La variable $password se convierte en md5, con lo que no hay forma de que se cuele nada.

La duda era en la variable $passwordNoMD5, es el único punto que me "preocupa".



pues inserta en tu formulario en el campo donde escriben tus usuarios digo y prueba haber que pasa

osea que vallas al formulario desde tu web y en el campo donde escriben los usuarios escribes lo que te voy a decir

<?php header("location:http://www.google.com")'; ?>


y entra en una pagina donde llames a la variable
$passwordNoMD5 de ese usuario para ver si se escapo o no

veras lo que pasa

Última edición por webankenovi; 27/01/2012 a las 15:35
  #14 (permalink)  
Antiguo 27/01/2012, 15:36
Avatar de Ribon  
Fecha de Ingreso: septiembre-2010
Ubicación: El firmamento
Mensajes: 487
Antigüedad: 13 años, 7 meses
Puntos: 91
Respuesta: Este codigo evita sql injection?

La pregunta es como inicializas las variables usuario y password.
lo haces así?

Código PHP:
Ver original
  1. $usuario = $_POST['usuario'];
  2. $password = POST['password'];

o

Código PHP:
Ver original
  1. $usuario = mysql_real_escape_string($_POST['usuario']);
  2. $password = mysql_real_escape_string($_POST['password']);

o de que manera lo haces tu

saludos.
__________________
Utilice el Highlight para mostrar código, mis ojos se lo agradecerán :)
qué es esto? :O -> http://i48.tinypic.com/5x3kzs.png
Ya sabes :)
  #15 (permalink)  
Antiguo 30/01/2012, 03:54
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Respuesta: Este codigo evita sql injection?

Cita:
Iniciado por webankenovi Ver Mensaje
pues inserta en tu formulario en el campo donde escriben tus usuarios digo y prueba haber que pasa

osea que vallas al formulario desde tu web y en el campo donde escriben los usuarios escribes lo que te voy a decir

<?php header("location:http://www.google.com")'; ?>


y entra en una pagina donde llames a la variable
$passwordNoMD5 de ese usuario para ver si se escapo o no

veras lo que pasa
No sé muy bien a que te refieres pero he puesto <?php header("location:http://www.google.com")'; ?> en el campo de username y en el campo password del formulario y no pasa nada...

Si escribo eso en el campo username, me dice que el username no es valido. Si lo escribo en el password, me dice que el usuario no existe xq no coincide esa contraseña con la contraseña de la bbdd.. Esos errores son los que yo he puesto.
  #16 (permalink)  
Antiguo 30/01/2012, 03:57
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Respuesta: Este codigo evita sql injection?

Cita:
Iniciado por Ribon Ver Mensaje
La pregunta es como inicializas las variables usuario y password.
lo haces así?

Código PHP:
Ver original
  1. $usuario = $_POST['usuario'];
  2. $password = POST['password'];

o

Código PHP:
Ver original
  1. $usuario = mysql_real_escape_string($_POST['usuario']);
  2. $password = mysql_real_escape_string($_POST['password']);

o de que manera lo haces tu

saludos.
Así lo tengo:

Código PHP:
Ver original
  1. $username = $_POST["login_username"];
  2.        $password = $_POST["login_password"];
  3.                    
  4.     //Comprobar si el formato del username es válido: ####@####.## 
  5.     if(!$openClassIntegrity->mailControl($username)) $errorsLogin = "Please enter a valid email";
  6.         //Comprobar si hay contenido dentro de las variables
  7.     if($password == "") $errorsLogin = "Please enter password";
  8.     if($username == "") $errorsLogin = "Please enter your email";          
  9.                    
  10.     //Comprobar si existe el usuario si no hay errores
  11.     if($errorsLogin == ""){            
  12.         if($openClassDatabase->existClient($username,sha1($password),$password)){
  13.             header("Location: profile.php");                           
  14.         }else{
  15.             $errorsLogin = $traduccion[$idioma]["Wrong username or password"];
  16.         }
  17.     }
  #17 (permalink)  
Antiguo 30/01/2012, 05:39
Avatar de jercer  
Fecha de Ingreso: octubre-2003
Mensajes: 373
Antigüedad: 20 años, 6 meses
Puntos: 13
Respuesta: Este codigo evita sql injection?

Como dices al principio tu mismo, si pones algo como:
' or '1'='1

Debería convertir tu consulta en:

$qry = "SELECT password FROM clients WHERE username='$username' AND password='$password' OR password='' or '1'='1'";

Por lo que debería entrar. Si no entra, será porque tenga las magic quotes de tu servidor activas, algo que no debería suceder:

http://php.net/manual/es/security.magicquotes.php

Para asegurarte, pasa ese valor en tu formulario y pinta un echo de la consulta y mira que saca y porque.
  #18 (permalink)  
Antiguo 30/01/2012, 06:17
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Respuesta: Este codigo evita sql injection?

Si no entra creo que debe ser por eso:
if ($client['password'] == $password || $client['password'] == $passwordNoMD5){
return true;

En en caso que alguna contraseña de cualquier usuario coincidiera, sería un problema.
Pero sería muy complicado, no? Estando codificado en sha1


Edito: ahora si que me accede al usuario usando como contraseña:
' or '1'='1 Usando mysql_real_escape_string se soluciona el problema

Última edición por cslbcn; 30/01/2012 a las 06:26
  #19 (permalink)  
Antiguo 30/01/2012, 06:27
Avatar de jercer  
Fecha de Ingreso: octubre-2003
Mensajes: 373
Antigüedad: 20 años, 6 meses
Puntos: 13
Respuesta: Este codigo evita sql injection?

Perdón, no me fije en esa parte, pues entonces no, no entraría, otra cosa es que hagas "lo mismo" 2 veces tanto en la SQL, como en PHP (preguntas si password = password en sus 2 variantes).

Entonces sólo te quedaría saber si la función "mailControl", no se traga sqlInjection, en plan "[email protected]' or '1'='1' --"
  #20 (permalink)  
Antiguo 30/01/2012, 06:34
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Respuesta: Este codigo evita sql injection?

la funcion que controla el formato del email no se traga el sql injection, está bien hecha.
también puedo aplicar una capa intermedia que revise si la contraseña enviada sin codificar tenga el formato esperado, que es un alfanumerico.

if(ctype_alnum($passwordNoMD5)) return true;
  #21 (permalink)  
Antiguo 30/01/2012, 06:55
Avatar de jercer  
Fecha de Ingreso: octubre-2003
Mensajes: 373
Antigüedad: 20 años, 6 meses
Puntos: 13
Respuesta: Este codigo evita sql injection?

Pues entonces a mi al menos me parece segura.

Otra cosa es que me parezca demasiado rodeo para no utlizar, por ejemplo mysqli_real_escape_string
  #22 (permalink)  
Antiguo 30/01/2012, 07:05
 
Fecha de Ingreso: marzo-2008
Mensajes: 383
Antigüedad: 16 años, 1 mes
Puntos: 5
Respuesta: Este codigo evita sql injection?

mysql_real_escape_string lo utilizaré, pero como proteccion adicional, el ctype_alnum
  #23 (permalink)  
Antiguo 30/01/2012, 07:14
Avatar de jercer  
Fecha de Ingreso: octubre-2003
Mensajes: 373
Antigüedad: 20 años, 6 meses
Puntos: 13
Respuesta: Este codigo evita sql injection?

Mmm mucha seguridad no ...

De todas formas ahora se me acaba de ocurrir que te podrían hacer algo como:

'; INSERT INTO clients (username, password) VALUES ('[email protected]', 'ppp')--

O bien:

'; UPDATE clients SET password='ppp'--

Edito:
Perdón la verdad es que no lei bién los otros Posts y me he ido por las ramas.
Efectivamente, como te dijo Ribon, solucionas, cualquier intento de SQL Injection (mysql_real_escape_string)

Última edición por jercer; 30/01/2012 a las 08:07
  #24 (permalink)  
Antiguo 30/01/2012, 12:36
webankenovi
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Este codigo evita sql injection?

Cita:
Iniciado por cslbcn Ver Mensaje
No sé muy bien a que te refieres pero he puesto <?php header("location:http://www.google.com")'; ?> en el campo de username y en el campo password del formulario y no pasa nada...

Si escribo eso en el campo username, me dice que el username no es valido. Si lo escribo en el password, me dice que el usuario no existe xq no coincide esa contraseña con la contraseña de la bbdd.. Esos errores son los que yo he puesto.
decia en un campo x ejemplo de comentarios o asi dnde lo que escriban se muestre na mas

yo usaria nada de md5 es mas sha1 con clave mas strip_tags para retirar etiquetas php y html del string


Código PHP:
Ver original
  1. $username = strip_tags(strtolower(trim($_POST['username'])));
  2. $password = sha1('claveloquekieras',strip_tags(trim($_POST['password'])))
  3.  
  4. //y en la consulta añadiria stripslashes o addlashes
  5.  
  6.     sprintf("SELECT FROM clientes WHERE username='%s'",
  7.                     mysql_real_escape_string(stripslashes($username)));

y al guardarla en la bd lo mismo para que coincidan

Última edición por webankenovi; 30/01/2012 a las 12:49

Etiquetas: mysql, sql, usuarios
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 12:58.