Foros del Web » Programando para Internet » PHP »

Evitar SQL Injection

Estas en el tema de Evitar SQL Injection en el foro de PHP en Foros del Web. Hola! Ya he terminado la bendita web...pero ahora he recordado que las consultas no las tengo protegidas contra SQL Injection, asi que les pido una ...
  #1 (permalink)  
Antiguo 26/12/2009, 06:47
 
Fecha de Ingreso: diciembre-2009
Ubicación: Linz
Mensajes: 48
Antigüedad: 14 años, 4 meses
Puntos: 1
Exclamación Evitar SQL Injection

Hola!

Ya he terminado la bendita web...pero ahora he recordado que las consultas no las tengo protegidas contra SQL Injection, asi que les pido una ayuda.

Una de las más comunes de mis consultas son del tipo

Código PHP:
    $fecha date('Y-m-d');
    
$query "SELECT SUM(total) as totales FROM orden WHERE fecha = '$fecha' ";
    
$result mysql_query($query) or die(mysql_error());
    
$res_fotos mysql_fetch_array($result);
    
$fotos_hechas $res_fotos["totales"];
    return 
$fotos_hechas
He buscado en guguel a ver cómo es que se proteje contra eso, y he encontrado que lo mejor es usar
Código PHP:
$query sprintf("SELECT * FROM libros WHERE autor='%s'",
mysql_real_escape_string($autor_nombre));
mysql_query($query); 
Asi que me gustaría saber si, en mi ejemplo, este sería una consulta correcta y pretegida:
Código PHP:
$fecha date('Y-m-d');
$query sprintf("SELECT SUM(total) as totales FROM orden WHERE fecha = '%s'",
mysql_real_escape_string($fecha));
$result_mysql_query($query);
$res_fotos mysql_fetch_array($result);
$fotos_hechas $res_fotos["totales"];
return 
$fotos_hechas
Gracias!!
Y felices fiestas :)
  #2 (permalink)  
Antiguo 26/12/2009, 07:28
Avatar de MarioAraque
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Valencia
Mensajes: 1.398
Antigüedad: 14 años, 6 meses
Puntos: 265
Respuesta: Evitar SQL Injection

Hola amatosg,

Te comento que la funcion mysql_real_escape_string sirve para escapar caracteres y evitar SQL Injection, seguro que eso lo tenes claro. Sin embargo vos lo estas aplicando a una funcion que va a devolver un valor determinado siempre (en este caso date), por lo que no se si valga la pena usarla en este caso, es como si yo ponga lo siguiente:

Código PHP:
$valor "hola";
$valor2 mysql_real_escape_string($valor); 
Despues, usar sprintf ayuda mucho, ya que imprimir una cadena con formato ayuda mucho en los casos que, en un formulario, tenes que ingresar valores numericos (campo edad por ejemplo), y evitar que te pongan algo del estilo "OR 1=1", q es un tipo string.

Saludos.
  #3 (permalink)  
Antiguo 26/12/2009, 07:45
 
Fecha de Ingreso: diciembre-2009
Ubicación: Linz
Mensajes: 48
Antigüedad: 14 años, 4 meses
Puntos: 1
Respuesta: Evitar SQL Injection

Hola Mario!

Te cuento un poco. En el ejemplo que pongo, pues como ya sabrás, solo pido un valor en la base de datos. Pero como comentas, tengo varios formularios de insersión de datos. Es en ese caso cuando debería usar el sprintf?

Muchas gracias!
  #4 (permalink)  
Antiguo 26/12/2009, 08:05
Avatar de MarioAraque
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Valencia
Mensajes: 1.398
Antigüedad: 14 años, 6 meses
Puntos: 265
Respuesta: Evitar SQL Injection

Yo, siendo sincero, no me fijo en que casos usar sprintf o no, lo uso siempre y me ahorro cualquier tipo de problema que pueda haber. Total cuando te acostumbras es muy facil!

Sin embargo, a la hora de usar mysql_real_escape_string si que me fijo, q lo aplique a datos a los que valga la pena.

El ejemplo del nombre del autor es muy claro, lo que siempre habra en el '%s" sera una cadena. Pero en el caso de querer poner un campo edad, tendrias que poner un numero no es asi? Entonces deberias poner '%d' (decimal), y si alguien pone en ese campo "OR 1=1" entonces todo falla y no se imprime de manera correcta, por lo que la consulta no se hace.

Saludos.
  #5 (permalink)  
Antiguo 26/12/2009, 08:35
 
Fecha de Ingreso: diciembre-2009
Ubicación: Linz
Mensajes: 48
Antigüedad: 14 años, 4 meses
Puntos: 1
Respuesta: Evitar SQL Injection

bueno, solo una cosa. Yo tengo la web protegida con contraseña (por DB) y si uno quiere acceder a la web, tienes que estar logueado, sino, te manda a lapagina de login. A este formulario de login se le puede hacer un inject?

Otra cosa, ya que tengo la web "protegida" con contraseña...será suficiente con proteger de inject a la página de login?

muchas gracias
  #6 (permalink)  
Antiguo 26/12/2009, 08:40
Avatar de MarioAraque
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Valencia
Mensajes: 1.398
Antigüedad: 14 años, 6 meses
Puntos: 265
Respuesta: Evitar SQL Injection

Si usas la funcion mysql_real_escape_string para tomar los datos del formulario (el nombre y la contraseña), y usas sprintf para hacer la consulta a la DB, entonces no deberias tener problemas de injection.

No comprendi mucho lo que quisiste decir, vos mencionas que siempre se aplique sprintf y mysql_real_escape string? O con solo hacerlo en el login es suficiente? Yo creo que lo tenes que hacer en todos los casos...

Saludos.
  #7 (permalink)  
Antiguo 26/12/2009, 09:02
 
Fecha de Ingreso: diciembre-2009
Ubicación: Linz
Mensajes: 48
Antigüedad: 14 años, 4 meses
Puntos: 1
Respuesta: Evitar SQL Injection

pues si, quería poner el sprintf y el mysql_real_scape solo en el login. Pero dices que lo tengo que hacer en todos?

pensaba hacerlo solo en el login porque la cantidad de usuarios que van a utilizar la aplicación es mínima (no más de 5-10 personas) y la creacion de nuevos usuarios las hace el administrador del sistema =/
  #8 (permalink)  
Antiguo 26/12/2009, 09:08
Avatar de MarioAraque
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Valencia
Mensajes: 1.398
Antigüedad: 14 años, 6 meses
Puntos: 265
Respuesta: Evitar SQL Injection

Bueno en eso tenes razon, ahora entendi todo lo que me queres decir.

El login debe tener nada mas las verificaciones porque es el unico lugar desde donde se conectan los usuarios!!
En caso de que entren a una pagina sin estarlo, entonces los tenes que redireccionar al login, y ahi que inicien sesion!

Saludos.
  #9 (permalink)  
Antiguo 26/12/2009, 09:35
Avatar de jackson666  
Fecha de Ingreso: noviembre-2009
Ubicación: Buenos Aires, Argentina
Mensajes: 1.971
Antigüedad: 14 años, 5 meses
Puntos: 65
Respuesta: Evitar SQL Injection

No seria mas facil chequear los datos que son ingresados a tu base con expresiones regulares?
Buscando palabras como DROP, TRUNCATE, etc etc que puedan afectar tu tabla??
__________________
HV Studio
Diseño y desarrollo web
  #10 (permalink)  
Antiguo 26/12/2009, 09:42
 
Fecha de Ingreso: enero-2009
Mensajes: 408
Antigüedad: 15 años, 3 meses
Puntos: 14
Respuesta: Evitar SQL Injection

Lo más facil no es validar los datos contra regexp ya que afectan el rendimiento de tu aplicación web , lo normal y eficiente es separar la aplicación en capas y la capa en donde se maneja las conexiones a la base de datos implementarla con algun buen manejador de base datos , es decir una capa de abstracción que se encargue de realizar todo lo que sea consultas sql y las validaciones correspondientes ,antes existia , va , aún existe ADODB que genera consultas 100 % seguras pero PHP tiene en forma nativa a PDO que tambien genera consultas seguras y es mas eficiente que ADO.

Saludos
  #11 (permalink)  
Antiguo 26/12/2009, 21:05
 
Fecha de Ingreso: diciembre-2009
Ubicación: Linz
Mensajes: 48
Antigüedad: 14 años, 4 meses
Puntos: 1
Respuesta: Evitar SQL Injection

hola jonatanc

la verdad es que no he entendido nada de lo que has dicho. Hablas de capas y de acrónimos sin sentido :(

Podrías por favor explicar, aunque sea un poco, lo de las capas? suena interesante (y me creo que tiene que ser más eficiente de como lo tengo hecho yo...)

Saludos y gracias!
  #12 (permalink)  
Antiguo 26/12/2009, 23:12
 
Fecha de Ingreso: enero-2009
Mensajes: 408
Antigüedad: 15 años, 3 meses
Puntos: 14
Respuesta: Evitar SQL Injection

Estimado no hablo sin sentido , hablo de forma tecnicamente correcta , a lo que me refiero con capas es que una aplicación web usted la puede dividir suponga segun el patrón de diseño MVC (Modelo - Vista - Controlador) , bueno teniendo este concepto ya introducido lo que me refiera a que usted podria plantear su aplicación en forma "cebolla" capas con la DB (Base de datos) es algo asi:

Suponga que dispone de este codigo (sin utilizar la tecnica de capas de abstracción):

Código PHP:
Ver original
  1. <?php
  2.  
  3. $link = mysql_connect($server,$user,$pwd);
  4. mysql_select_db($db,$link);
  5.  
  6. $consulta=mysql_query("SELECT * FROM goles WHERE autornombre='Messi'",$link);
  7.  
  8. ?>

El mismo codigo usando una capa de abstracción (fijate que la invente yo solamente para el ejemplo , la interface ni la libreria existen):


Código PHP:
Ver original
  1. <?php
  2.  
  3. include('alguna_capa_de_abstraccion_my_sql.php');
  4.  
  5. $link = new Capa($server,$user,$pwd,$db);
  6.  
  7. $consulta=$link->query("SELECT * FROM goles WHERE autornombre='Messi'");
  8.  
  9. ?>

Fijate la diferencia , en el primer codigo accedes directamente a funciones nativas de PHP , mientras que en el segundo codigo empleas la interface brindada por tu capa de abstracción mysql , de este modo en dicha capa puedes realizar todo tipo de validaciones y no necesitas propagar en forma manual dicho cambio a tu codigo , ya que en toda tu aplicación para realizar una consulta sql utilizaras query() y no utilizar mysql_query (nativa) , esto es una tecnica mucho más correcta para el diseño de aplicaciones escalables y aumenta tu productividad y seguridad de la aplicación (siempre que la capa de abstracción sea buena).

La ventaja prioritaria tmb de la utilización de capas de abstracción para manejo de base de datos es que si tu utilizas funciones nativas en el desarrollo de tu aplicación , digamos mysql_connect , al migrar ponele tu servidor a mssql porque la empresa lo quiere asi ahora , deberias cambiar todo lo que diga mysql_connect por mssql_connect , en cambio utilizando una capa de abstracción esto lo evitas y solo cambias en el fichero de configuracion de tu capa de abstracción (ya sea ADODB , PDO o cual fuere) el driver (manejador) que tienes que usar que ahora en vez de mysql sera mssql , es decir tu aplicación es totalmente migrable sin esfuerzos y eso enriquece tus desarrollos y te facilita la vida.

Espero que te haya quedad mas claro los conceptos :).

Por cierto me olvidaba al utilizar estas librerias securizas totalmente las consultas SQL , te olvidas de purificar los datos , solo te centras en diseñar la logica de la aplicación , por eso tiene muchisimas ventajas utilizarlas :).

Cualquier duda pregunta.

Saludos

Link referencia: http://adodb.sourceforge.net/
Link referencia: http://www.jourmoly.com.ar/php-data-objects-pdo/

Última edición por jonatanc; 26/12/2009 a las 23:20
  #13 (permalink)  
Antiguo 27/12/2009, 05:53
 
Fecha de Ingreso: diciembre-2009
Ubicación: Móstoles , Madrid
Mensajes: 23
Antigüedad: 14 años, 4 meses
Puntos: 1
Respuesta: Evitar SQL Injection

Muy buena a todos.

Estaba viendo este trhread y vi que estais diciendo que usar mysql_real_escape_string(), no es del todo seguro, entonces ¿Alguien puede decirme que es sprintf?¿Como se usa? Estoi muy interesado en este tipo de problema. Siento desviar el tema

Saludos

Última edición por Siquillote; 27/12/2009 a las 06:08
  #14 (permalink)  
Antiguo 27/12/2009, 06:04
 
Fecha de Ingreso: diciembre-2009
Ubicación: Linz
Mensajes: 48
Antigüedad: 14 años, 4 meses
Puntos: 1
Respuesta: Evitar SQL Injection

Hola Jonatan!

No me refería a que lo que hayas dicho estubiera mal explicado o algo asi, es que para mi no tienen sentido jejeje.

Con respecto a las capas...me han quedado muchisimas dudas, porque aún no se programar PHP de esa manera, por lo que mejor es meterme una BUENA leída de algun libro (web) para aprender un poco más :)

Tambien quiero aclarar que las llamadas a las DB las hago por funciones, que están en un archivo llamado "funciones.php" :)
  #15 (permalink)  
Antiguo 27/12/2009, 08:21
Avatar de jackson666  
Fecha de Ingreso: noviembre-2009
Ubicación: Buenos Aires, Argentina
Mensajes: 1.971
Antigüedad: 14 años, 5 meses
Puntos: 65
Respuesta: Evitar SQL Injection

Cita:
Iniciado por amatosg Ver Mensaje
Hola Jonatan!

No me refería a que lo que hayas dicho estubiera mal explicado o algo asi, es que para mi no tienen sentido jejeje.

Con respecto a las capas...me han quedado muchisimas dudas, porque aún no se programar PHP de esa manera, por lo que mejor es meterme una BUENA leída de algun libro (web) para aprender un poco más :)

Tambien quiero aclarar que las llamadas a las DB las hago por funciones, que están en un archivo llamado "funciones.php" :)
Yo creo que seria mejor que busques una manera mas simple para evitar el problema. Me refiero a que lo que dice jonatanc es muy acertado, pero que te conviene mas en este momento? Aprender OOP o encontrarle la vuelta con la programacion estructurada?

O sea, no digo que NO haya que usar OOP, de hecho, seria lo ideal. Pero seria una perdida de tiempo muy grande, para un problema que puede tener solucion rapidamente.

Por ejemplo, si usaras expresiones regulares:

Código PHP:

$user
=$_POST['user'];

preg_match("/\drop\b/i"strtolower($user));

preg_match("/\truncate\b/i"strtolower($user));

/** Y expresiones por el estilo.
  * El rendimiento de tu aplicacion no 
  * se va a ver afectado de tal forma
  * que ande SUPER lento, es mas
  * no creo ni que lo notes. */ 
__________________
HV Studio
Diseño y desarrollo web
  #16 (permalink)  
Antiguo 28/12/2009, 00:25
 
Fecha de Ingreso: diciembre-2009
Ubicación: Linz
Mensajes: 48
Antigüedad: 14 años, 4 meses
Puntos: 1
Respuesta: Evitar SQL Injection

Muchas gracias por lo de preg_match (ya he aprendido una cosa nueva :) )

Aunque aún continúo con la misma duda: Es necesario asegurar todas las consultas e insert a DB? Lo digo porque tengo solo un máximo de 10 usuarios (solo el usuario "maestro" puede añadir usuarios nuevos). Por eso preguntaba si con añadir la seguridad en el formulario de login bastaría?

Hombre, si hay que rehacer todas las consultas, las hago sin problemas :) pero era solo por asegurarme ;)

Muchas gracias
  #17 (permalink)  
Antiguo 28/12/2009, 00:37
 
Fecha de Ingreso: diciembre-2009
Ubicación: Linz
Mensajes: 48
Antigüedad: 14 años, 4 meses
Puntos: 1
Respuesta: Evitar SQL Injection

ahh, y el usuario que está asignado a la DB solo tiene privilegios de INSERT y SELECT ;)
  #18 (permalink)  
Antiguo 28/12/2009, 06:51
Avatar de jackson666  
Fecha de Ingreso: noviembre-2009
Ubicación: Buenos Aires, Argentina
Mensajes: 1.971
Antigüedad: 14 años, 5 meses
Puntos: 65
Respuesta: Evitar SQL Injection

Si, la idea seria que de ahora en mas hagas esa comprobacion en el formulario de INSCRIPCION, no en el de login. Porque el que ya esta logueado es porque ya se registro =)
No tendria sentido ponerlo en el de login, se entiende? Si lo nombres de usuario no cambian (quiero creer)
__________________
HV Studio
Diseño y desarrollo web
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 23:21.