Foros del Web » Programando para Internet » PHP »

duda mysql_num_rows

Estas en el tema de duda mysql_num_rows en el foro de PHP en Foros del Web. Hola verán tengo un formulario típico de logueo, en el que se introducen el nombre y password y lo envia por POST al loguin.php que ...
  #1 (permalink)  
Antiguo 24/09/2007, 19:35
 
Fecha de Ingreso: marzo-2007
Mensajes: 12
Antigüedad: 17 años, 1 mes
Puntos: 1
duda mysql_num_rows

Hola verán tengo un formulario típico de logueo, en el que se introducen el nombre y password y lo envia por POST al loguin.php que tiene el siguiente código:
Código:
<? 
if($_POST['nombre'] && $_POST['password'])
{
	$nombre = $_POST['nombre'];
	$password = $_POST['password'];
	// Conectamos con la base de datos
	$dbhost = 'localhost';
	$dbuser = 'root';
	$dbpass = 'xxxxx';
	$conexion = @mysql_connect($dbhost, $dbuser, $dbpass) or die("Fallo al conectar con la base de datos");
	@mysql_select_db('mibase', $conexion) or exit(mysql_error());
	// Comprobamos que el usuario y password son válidos
	$consulta = "SELECT * FROM Usuarios WHERE nombre='$nombre' and password='$password'";
	$resultado = mysql_query($consulta);
	if(mysql_num_rows($resultado) == 1)
		echo "ACCESO PERMITIDO";
	else
		echo "ACCESO DENEGADO";
}
else
	echo "Tiene que rellenar los dos campos";
?>
En la base de datos tengo un usuario que se llama admin (con pass:123) y otro que se llama prueba (con pass 333). El caso es que si pongo:
nombre:admin
password:123
Me dice que tengo acceso permitido y si pongo un echo mysql_num_rows($resultado) me da como resultado 1, es decir, sólo ha afectado a una fila. Todo correcto.

El caso es que estoy mirando sobre sql-injection y si por ejemplo pongo
nombre:admin
password:1'OR'1'='1
me dice acceso denegado ya que si hago un echo mysql_num_rows($resultado) me da como resultado 2.

¿Porque me da resultado 2? En teoria solo se ve afectada la fila del admin, la del usuario prueba no interviene para nada, ya que la consulta sql quedaría:
$consulta = "SELECT * FROM Usuarios WHERE nombre='admin' and password='1'OR '1'='1'";

A ver si alguien me puede decir porque da como resultado 2... gracias
  #2 (permalink)  
Antiguo 24/09/2007, 20:48
Avatar de BrujoNic
Super Moderador
 
Fecha de Ingreso: noviembre-2001
Ubicación: Costa Rica/Nicaragua
Mensajes: 16.935
Antigüedad: 22 años, 5 meses
Puntos: 655
Re: duda mysql_num_rows

Trasladado de BD a PHP. Favor no poner código de programación en BD.

Función de la sección de Base de Datos
__________________
La tecnología está para ayudarnos. No comprendo el porqué con esa ayuda, la gente escribe TAN MAL.
NO PERDAMOS NUESTRO LINDO IDIOMA ESPAÑOL
  #3 (permalink)  
Antiguo 24/09/2007, 21:40
 
Fecha de Ingreso: septiembre-2007
Mensajes: 60
Antigüedad: 16 años, 7 meses
Puntos: 1
Re: duda mysql_num_rows

es que para empezar ese codigo de inyeccion sql esta erroneo si quieres que te de acceso deberia ser algo como

' or '1'='1 tanto es usuario como en contraseña si es un solo campo creo que debe ser algo asi ' or '1'='1 -- y que me corrigan si me equivoco
  #4 (permalink)  
Antiguo 24/09/2007, 22:40
Avatar de ramoncito  
Fecha de Ingreso: febrero-2003
Ubicación: Viña del Mar
Mensajes: 224
Antigüedad: 21 años, 1 mes
Puntos: 10
Re: duda mysql_num_rows

Concuerdo con venedan, el error está en la sentencia OR, el cual no debería existir ya que siempre dará esa sentencia como verdadera (1=1), quitalo porque además es una falencia de seguridad.

Saludos
__________________
:pensando: Ramon Martinez... Chile :adios:
  #5 (permalink)  
Antiguo 25/09/2007, 00:38
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 20 años, 7 meses
Puntos: 41
Re: duda mysql_num_rows

Siempre que tengas una duda de este tipo prueba a imprimir en pantalla la sentencia SQL generada. En tu caso debería ser algo así:

SELECT * FROM Usuarios WHERE nombre='admin' and password='1' OR '1'='1'

Si ves en el manual de referencia de MySQL donde se habla acerca de la precedencia de los operadores verás que el "OR" se evalúa antes que el "AND".

Tu consulta sería como:
"Dame todos los usuarios cuyo (nombre sea Admin Y su password sea '1') o (donde 1=1)"

Todos los usuarios cumplen 1=1 ----> True
Eso es suficiente para que te devuelva ese registro.

Tal como está, debería devolverte todos y cada uno de los registros de tu tabla "usuarios". Si te devuelve 2 es seguramente porque tienes sólo 2 registros en tu tabla.

Saludos
  #6 (permalink)  
Antiguo 25/09/2007, 02:06
Avatar de caerolus  
Fecha de Ingreso: agosto-2004
Ubicación: Madrid, España
Mensajes: 280
Antigüedad: 19 años, 8 meses
Puntos: 1
Re: duda mysql_num_rows

Cita:
Iniciado por jpinedo Ver Mensaje
Si ves en el manual de referencia de MySQL donde se habla acerca de la precedencia de los operadores verás que el "OR" se evalúa antes que el "AND".
Precisamente es al contrario: and se evalúa antes que or, como la multiplicación se evalúa antes que la suma. Por eso sería equivalente a (user=... and pass=...) or (1=1).
__________________
Mi página personal: Julián Urbano
  #7 (permalink)  
Antiguo 25/09/2007, 06:33
 
Fecha de Ingreso: marzo-2007
Mensajes: 12
Antigüedad: 17 años, 1 mes
Puntos: 1
Re: duda mysql_num_rows

Hola, en primer lugar gracias por contestar.

Respecto a las respuestas de venedan y ramoncito tengo que decirles que la inyección sql no es el problema, ya que si pongo por ejemplo, if(mysql_num_rows($resultado) > 0 me da como resultado ACCESO PERMITIDO.

Respecto a jpinedo y caerolus, Jpinedo como dice caerolus en la página web que me has pasado sale la predencia de operaciones de menor a mayor y yo diria que siempre AND tiene mayor precedencia que OR.

Entonces la consulta nos quedaria como dices:
"Dame todos los usuarios cuyo (nombre sea Admin Y su password sea '1') o (donde 1=1)"

entonces seria false or true = true --> Devuelve todos los registros

En cambio si pongo el password verdadero:
"Dame todos los usuarios cuyo (nombre sea Admin Y su password sea '123') o (donde 1=1)"
entonces seria true or true = true --> ¿Porque solo devuelve 1 registro?

Lo único que me viene a la cabeza es que en el primer caso, donde el password es incorrecto, como la primera condición es false quedaría:
"Dame todos los usuarios cuyo [esto es falso] o (donde 1=1)"
Entonces devuelve todos los campos

En el otro caso, en el que el password es correcto quedaría:
"Dame todos los usuarios cuyo (nombre sea Admin Y su password sea '123') o [como ya es verdadero, esto no sirve]"
como todo es verdadero, se ejecuta primero la condicion (nombre sea Admin Y su password sea '1') y ya no sigue comparando, con lo que solo se ve afectada 1 fila, la fila del admin.

Estoy en lo cierto? Gracias, saludos.

Última edición por jose.va18; 25/09/2007 a las 06:50
  #8 (permalink)  
Antiguo 25/09/2007, 08:09
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Re: duda mysql_num_rows

Te recomiendo si tienes algun gestor de bases de datos, que pongas el Query generado en tu consola y examines los resultados que te arroja.

Saludos.
  #9 (permalink)  
Antiguo 25/09/2007, 10:15
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 20 años, 7 meses
Puntos: 41
Re: duda mysql_num_rows

Cita:
Iniciado por jose.va18 Ver Mensaje
En el otro caso, en el que el password es correcto quedaría:
"Dame todos los usuarios cuyo (nombre sea Admin Y su password sea '123') o [como ya es verdadero, esto no sirve]"
como todo es verdadero, se ejecuta primero la condicion (nombre sea Admin Y su password sea '1') y ya no sigue comparando, con lo que solo se ve afectada 1 fila, la fila del admin.

Estoy en lo cierto? Gracias, saludos.
Eso es cierto para el registro donde el usuario es Admin... entonces te devuelve ese registro. Pero la comparación no termina ahí. En el siguiente registro, al no ser Admin, no cumple la primera parte, pero sí cumple la segunda (1=1), así que también lo devuelve.

Saludos
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 06:47.