Funcionamiento de mysql_real_escape_string()

Iniciado por Gambinoh, 30 Diciembre 2010, 18:55 PM

0 Miembros y 1 Visitante están viendo este tema.

Gambinoh

Hola a todos. Tengo algunas dudas a cerca de la función de PHP mysql_real_escape_string.

Se el funcionamiento y he leído su descripción en php.net pero no comprendo del todo porqué evita una inyección sql.

Por ejemplo si  mysql_real_escape_string() escapa caracteres tipo ", ', *,/, etc. quiere decir que los interpreta no como comillas que contienen un string sino como parte del texto (según yo tengo entendido). Entonces si yo tengo este query:
Citar
$sql = "SELECT * FROM tabla WHERE campo = '$id' ORDER BY id ASC  LIMIT $inicio, $fin";

$query = mysql_query($sql);

La inyección sql debería de querer atacar reemplazando la variable $id por código que sería interpretado como una instrucción sql que en el peor de los casos directamente modificaría mi tabla o daría un error del que el "maleante xD" obtendría información.

Entonces el atacante escribiría algo como:

Citarpagina.php?"codigomalicioso"=$id

Luego yo al usar en la recepción $_GET['id'], si lo coloco de esta manera estaría filtrando su comentario malicioso:

Citar$id = mysql_real_escape_string($_GET['id']);

¿Entonces mysql_real_escape_string lo que haría es hacer que se vean todas las ",',*,/,etc. del códico o cómo?

Si estoy suponiendo alguna barbaridad decírmelo xD, sólo quiero enterarme de que falla en mi razonamiento.

Por otro lado parece que el peligro de la inyección sql en principio estaría en la recepción $_GET y $_POST de números, letras y operadores intruducidos vía URL.

Veo que hay gente que coloca entre dos puntos la $id tal que así:

Citar... FROM tabla WHERE campo = '.$id.' ....

¿Explicación a esos dos puntos?

¿Alguien me explica la lógica de usar esto ( ' or '1'='1) como contraseña?  Or quiere decir True si alguna de las dos posibilidades es verdadera. La segunda está claro que lo es. ¿Las comillas son para simular espacios entre los operadores y los números?

Pero ¿en que afectaría usar ahí mysql_real_escape_string?

Que en lugar de or 1 = 1 se leería ' or '1'='1?

¿En que partes de mi código a parte de en aquellas en las que un valor es intruducido por URL y captado por GET o POST es necesario usar mysql_real_escape_string?





xassiz~

Con mysql_real_escape_string() haces que lo que escapes con ella no sea tomado como sentencia SQL.

Lo de la inyección ' or '1'='1.. imagínate un login tal que así:
Código (php) [Seleccionar]

$queryLogin = mysql_query("SELECT * FROM admin WHERE usuario = '".$_POST['usuario']."' AND password = '".$_POST['password']."'");


Ahí la consulta quedaría por ejemplo:
Código (SQL) [Seleccionar]
SELECT * FROM admin WHERE usuario = 'Gambinoh' AND password = '' or '1'='1'

Intepretando que si el password es '' o si 1 es igual a 1, lo que sería verdadero.


Deberas incluir esa función siempre que la sentencia SQL vaya afectada por la acción del usuario.

Gambinoh

#2
Claro, pero imagínate lo siguiente... tú dices cada vez, pero yo lo tengo así y creo que es igual, míralo y me lo confirmas.

Citar
//connect.php fuera de Document Root
include('archivos/connect.php');

mysql_select_db('base_de_datos', $conexion);

//Sólo las declaro una vez mediante mysql_real_escape_string
$id = mysql_real_escape_string($_GET['id']);
$pag = mysql_real_escape_string($_GET['pagina']);

//Aquí $id ya viene escapado y cuando llame a $pagina tmb
$sql = "SELECT * FROM tabla WHERE campo = '$id' ORDER BY id ASC  LIMIT $inicio, $fin";

//En este dato siguen estando escapadas las variables
$query = mysql_query($sql);

//Imprimo pero aquí no interviene tampoco el usuario que yo sepa

while($fila = mysql_fetch_assoc($query)) {
   echo $fila['campo_referencia'];

¿Donde pondrías tú la seguridad? es que yo lo veo bien, pero soy novato, igual me equivoco y hay fallos que podrían permitir una inyección sql.

xassiz~

Hombre no parece que haya errores, pero no se de donde sacas $inicio y $fin.

Gambinoh

Ok te explico... necesitaba las variables $inicio y $fin para con operadores matemáticos imprimir los resultados en dos bloques distintos (primero dos filas de la tabla en el primer bloque y luego tres filas en el segundo bloque) ya que entra siempre en juego una variable que es introducida por la URL que es en mi código "$pag".

O sea que si en la página pag=0 se imprimen 5 resultados siguiendo un orden Descendente con respecto al campo id, para que luego en pag=1 se impriman los otros 5 siguientes ha de variar el límite y para ello uso variables que representan números.

Es una chorrada en verdad. Lo que pasa es que no me expreso muy bien.


Venga un saludo y gracias ^^

xassiz~

Vale, mientras el usuario no ingrese esos datos sería seguro.