send
Grupo de Telegram
play_arrow
Este sitio utiliza cookies propias y de terceros. Si continúa navegando consideramos que acepta el uso de cookies. OK Más Información.

Evitar injeccion SQL

  • 21 Respuestas
  • 6161 Vistas

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

Desconectado alexander1712

  • *
  • Underc0der
  • Mensajes: 851
  • Actividad:
    0%
  • Reputación -2
    • Ver Perfil
    • El blog del programador
    • Email
« en: Enero 26, 2013, 12:45:04 pm »
Este post sale de mi baul de los recuerdos, asique es un poco viejo, pero aún aplica.



Bueno algo muy importante hoy en día al programar en PHP es evitarse una injeccion SQL, ¿como hacemos esto?, filtrando todas las variables que utilizen el $_POST y $_GET.

para filtrarlas podemos usar los comandos

strip_tags
stripslashes
mysql_escape_string

así:

$variable=strip_tags($_POST['algo'];
$variable=stripslashes($variable);
$variable=mysql_escape_string($variable);

y luego ya podemos usar la variable en una consulta a la DB :D



Hola,
El tema de seguridad web es un tema bastante amplio y no se deberia simplemente usar una u otra funcion simplemente para quedarnos tranquilos.
El lema en este tipo de situaciones es bastante sencillo: nunca confies en los datos que manda el usuario, y no solo me refiero a los datos que llegan por $_GET y por $_POST sino tambien cualquier dato que venga en las cabeceras de la peticion http.
La idea en estos casos, es filtrar la informacion y solo recibir los datos que esperamos, se pueden usar expresiones regulares para aumentar la seguridad, pero siempre la seguridad esta dada desde nuestra imaginacion. mas adelante cuando tenga un poco de tiempo realizare tutoriales sobre XSS, RFI, CRSF etc.

para aportar un poco mas sobre estas funciones que nos muestra el compañero alexmanycool

mysql_escape_string es una funcion que en realidad esta deprecada, deberia usarse mysql_real_escape_string en su lugar, esta funcion nos permite filtrar los datos antes de almacenarlos en la base de datos para asi estar mas seguros ante las inyecciones SQL

strip_tags nos permite remover las diferentes etiquetas html del codigo, deberia usarse para filtrar todos los datos de salida, cosa de no cambiar nuestra pagina por voluntad de otro  :¬¬:

htmlentities convierte todos los caracteres a su equivalente html, esto nos permite evitarnos de algunas inyecciones sobre todo de script y html, aunque claro es posible saltarsela, pero nos brinda algo de seguridad



si utilizas algun sistema de noticas o lo que sea y a la variables (ya sea de categoria o de la noticia) la asignas con un numero es decir por ejemplo 1 = noticias 2 = contacto etc...

podrias utilizar la funcion is_numeric() solo va a dejar continuar con la impresion o la ejecucion del script si el valor recibido solo es numerico.

tambien se puede forzar el tipo de dato numérico poniendo

$var = (int)$var;
o
$var = intval($var);

espero les haya sido util

saludos!
« Última modificación: Marzo 22, 2014, 01:55:49 pm por Expermicid »

Desconectado 2Fac3R

  • *
  • Underc0der
  • Mensajes: 231
  • Actividad:
    0%
  • Reputación 0
  • Why be a king, when you can be a god
    • Ver Perfil
  • Skype: rockeg_18
« Respuesta #1 en: Enero 26, 2013, 02:47:15 pm »
Comentar solamente que el strip_tags() y el htmlentities() no son para filtrar inyecciones SQL, sino para evitar XSS (y sus variantes), y de igual forma no son seguras dependiendo el sistema/entorno en que se apliquen.

En caso de que el dato sea string (que son los que más causan problemas) yo recomiendo addslashes() y/o mysql_real_escape_string() [en caso de usar MySQL].

Otra opción bastante fiable es usar PDO.
Buen post!
Zalu2

Desconectado WilyXem

  • *
  • Underc0der
  • Mensajes: 23
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
« Respuesta #2 en: Enero 26, 2013, 06:20:00 pm »
Sabeis que mysql_real_escape_string ha sido bypass-eado ?!

You are not allowed to view links. Register or Login
My Twitter: You are not allowed to view links. Register or Login

|| Security Researcher || Little PenTester || Member of UnderC0de.

One day, You gonna find me, I know that - WilyXem's Motto

Desconectado alexander1712

  • *
  • Underc0der
  • Mensajes: 851
  • Actividad:
    0%
  • Reputación -2
    • Ver Perfil
    • El blog del programador
    • Email
« Respuesta #3 en: Enero 26, 2013, 06:23:41 pm »
gracias por la aclaracion 2Fac3r jejeje. lo saqué de un post viejo y no lo miré de nuevo...

Código: You are not allowed to view links. Register or Login
Sabeis que mysql_real_escape_string ha sido bypass-eado ?!

http://blog.y-shahinzadeh.ir/2012/07/bypassing-mysql_real_escape_string-and-magic_quotes_gpc/

muy interesante, entonces que sugieres para evitar injecciones sql? que no hay forma de evitarlo?

el post habla de forzar el tipo de dato a int que es posible hacerlo también con $result = (int)$variable; pero esto solo aplica a valores numéricos. cuando se refiere a un string como una busqueda, que se podría hacer?

se me ocurre deshabilitar information_schema, pero no se si es posible...

saludos!
« Última modificación: Enero 26, 2013, 06:25:50 pm por alexander1712 »

Desconectado Once

  • *
  • Underc0der
  • Mensajes: 383
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
    • El blog de Once
  • Twitter: @don_once
« Respuesta #4 en: Enero 26, 2013, 06:42:03 pm »
You are not allowed to view links. Register or Login
gracias por la aclaracion 2Fac3r jejeje. lo saqué de un post viejo y no lo miré de nuevo...

Código: You are not allowed to view links. Register or Login
Sabeis que mysql_real_escape_string ha sido bypass-eado ?!

http://blog.y-shahinzadeh.ir/2012/07/bypassing-mysql_real_escape_string-and-magic_quotes_gpc/

muy interesante, entonces que sugieres para evitar injecciones sql? que no hay forma de evitarlo?

el post habla de forzar el tipo de dato a int que es posible hacerlo también con $result = (int)$variable; pero esto solo aplica a valores numéricos. cuando se refiere a un string como una busqueda, que se podría hacer?

se me ocurre deshabilitar information_schema, pero no se si es posible...

saludos!

You are not allowed to view links. Register or Login

Ahí te lo dice:
Citar
Esta extensión está obsoleta a partir de PHP 5.5.0, y será eliminada en el futuro. En su lugar, deberían usarse las extensiones MySQLi o PDO_MySQL. Véase también la guía MySQL: elegir una API y P+F relacionadas para más información. Las alternativas a esta función incluyen:

Saludos!






You are not allowed to view links. Register or Login

Desconectado alexander1712

  • *
  • Underc0der
  • Mensajes: 851
  • Actividad:
    0%
  • Reputación -2
    • Ver Perfil
    • El blog del programador
    • Email
« Respuesta #5 en: Enero 26, 2013, 07:01:24 pm »
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
gracias por la aclaracion 2Fac3r jejeje. lo saqué de un post viejo y no lo miré de nuevo...

Código: You are not allowed to view links. Register or Login
Sabeis que mysql_real_escape_string ha sido bypass-eado ?!

http://blog.y-shahinzadeh.ir/2012/07/bypassing-mysql_real_escape_string-and-magic_quotes_gpc/

muy interesante, entonces que sugieres para evitar injecciones sql? que no hay forma de evitarlo?

el post habla de forzar el tipo de dato a int que es posible hacerlo también con $result = (int)$variable; pero esto solo aplica a valores numéricos. cuando se refiere a un string como una busqueda, que se podría hacer?

se me ocurre deshabilitar information_schema, pero no se si es posible...

saludos!

You are not allowed to view links. Register or Login

Ahí te lo dice:
Citar
Esta extensión está obsoleta a partir de PHP 5.5.0, y será eliminada en el futuro. En su lugar, deberían usarse las extensiones MySQLi o PDO_MySQL. Véase también la guía MySQL: elegir una API y P+F relacionadas para más información. Las alternativas a esta función incluyen:

Saludos!

en realidad lo más probable es que mysqli también sea bypasseable, PDO no se.

es cierto que toda la rama de mysql_ está deprecated y que se usa mysqli.

es que no me preocupo mucho por ese tipo de cosas, me manejo con una clase que se encarga de hacer las consultas, y utiliza mysqli desde la anteúltima versión.

saludos!
« Última modificación: Enero 26, 2013, 07:02:56 pm por alexander1712 »

Desconectado WilyXem

  • *
  • Underc0der
  • Mensajes: 23
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
« Respuesta #6 en: Enero 26, 2013, 09:20:33 pm »
Citar


en realidad lo más probable es que mysqli también sea bypasseable, PDO no se.

es cierto que toda la rama de mysql_ está deprecated y que se usa mysqli.

es que no me preocupo mucho por ese tipo de cosas, me manejo con una clase que se encarga de hacer las consultas, y utiliza mysqli desde la anteúltima versión.

saludos!



Que tiene que ver MySQL con MySQL(i)=MySQL Injection ?
« Última modificación: Enero 26, 2013, 09:24:38 pm por WilyXem »
My Twitter: You are not allowed to view links. Register or Login

|| Security Researcher || Little PenTester || Member of UnderC0de.

One day, You gonna find me, I know that - WilyXem's Motto

Desconectado 2Fac3R

  • *
  • Underc0der
  • Mensajes: 231
  • Actividad:
    0%
  • Reputación 0
  • Why be a king, when you can be a god
    • Ver Perfil
  • Skype: rockeg_18
« Respuesta #7 en: Enero 26, 2013, 10:47:33 pm »
Aclarar que cuando uno se refiere a MySQLi es a la extensión MySQL improved no a la inyección.

Por el momento tengo entendido que PDO no es "bypasseable", aunque no estoy muy avanzado en su manejo, se supone que es para la seguridad en consultas de bases de datos.

Zalu2

Desconectado Xt3mP

  • *
  • Underc0der
  • Mensajes: 432
  • Actividad:
    0%
  • Reputación 0
  • Ellos me están buscando, pero yo los encontraré.
    • MSN Messenger - Xt3mP@h4x0rz.us
    • AOL Instant Messenger - Xt3mP@h4x0rz.us
    • Yahoo Instant Messenger - Xt3mP@h4x0rz.us
    • Ver Perfil
    • Xt3mP
« Respuesta #8 en: Enero 26, 2013, 10:50:05 pm »
Creo que si lo que quieres evitar es mysql injection, la manera más vieja y fácil es que "castees" a int, como dices, o que valides que la variable tenga un valor numérico exclusivamente (pues en tu caso la inyección se lleva a cabo mediante un ID numérico).
Cada vez que me das Karma me motivas

Desconectado alexander1712

  • *
  • Underc0der
  • Mensajes: 851
  • Actividad:
    0%
  • Reputación -2
    • Ver Perfil
    • El blog del programador
    • Email
« Respuesta #9 en: Enero 26, 2013, 11:15:09 pm »
You are not allowed to view links. Register or Login
Citar


en realidad lo más probable es que mysqli también sea bypasseable, PDO no se.

es cierto que toda la rama de mysql_ está deprecated y que se usa mysqli.

es que no me preocupo mucho por ese tipo de cosas, me manejo con una clase que se encarga de hacer las consultas, y utiliza mysqli desde la anteúltima versión.

saludos!



Que tiene que ver MySQL con MySQL(i)=MySQL Injection ?

antes de comentar por favor, investiga el tema que se trata.

gracias a todos los demás que comentaron, y xtemp, pero no puedo aplicar eso a un string por ejemplo la busqueda de un nombre :/

saludos

Desconectado HckDrk

  • *
  • Underc0der
  • Mensajes: 53
  • Actividad:
    0%
  • Reputación 0
  • http://127.0.0.1
    • Ver Perfil
    • HckDrk
« Respuesta #10 en: Enero 26, 2013, 11:51:50 pm »
para validar string con solo caracteres alfanuméricos pueden hacer uso de ctype_alnum()

mas info de la función en You are not allowed to view links. Register or Login

Saludos!

Desconectado alexander1712

  • *
  • Underc0der
  • Mensajes: 851
  • Actividad:
    0%
  • Reputación -2
    • Ver Perfil
    • El blog del programador
    • Email
« Respuesta #11 en: Enero 27, 2013, 12:22:46 am »
You are not allowed to view links. Register or Login
para validar string con solo caracteres alfanuméricos pueden hacer uso de ctype_alnum()

mas info de la función en You are not allowed to view links. Register or Login

Saludos!

eso no creo que ayude mucho a decir verdad :/ no lo se abría que probarlo.

saludos!

Desconectado Okol

  • *
  • Underc0der
  • Mensajes: 83
  • Actividad:
    0%
  • Reputación 0
  • Imaginando Programando & Avanzando!
    • Ver Perfil
    • Email
« Respuesta #12 en: Enero 27, 2013, 01:20:36 am »
You are not allowed to view links. Register or Login
Aclarar que cuando uno se refiere a MySQLi es a la extensión MySQL improved no a la inyección.

Por el momento tengo entendido que PDO no es "bypasseable", aunque no estoy muy avanzado en su manejo, se supone que es para la seguridad en consultas de bases de datos.

Zalu2
+1 mi bro 2Fact3R

Si no saben de lo que se habla en el tema no se quieran lucir.
Underc0de Manager!

Desconectado Xt3mP

  • *
  • Underc0der
  • Mensajes: 432
  • Actividad:
    0%
  • Reputación 0
  • Ellos me están buscando, pero yo los encontraré.
    • MSN Messenger - Xt3mP@h4x0rz.us
    • AOL Instant Messenger - Xt3mP@h4x0rz.us
    • Yahoo Instant Messenger - Xt3mP@h4x0rz.us
    • Ver Perfil
    • Xt3mP
« Respuesta #13 en: Enero 27, 2013, 06:40:10 am »
Alex, pues todo depende del concepto y de la plataforma a la cual quieras evitar inyección SQL. Hay distintas maneras para (NO PARCHAR),  sino para hacer más difícil la tarea de ejecutar ésta. Ya sea con PDO, utilizando expresiones regulares para validar lo que se ingresa, utilizando str_replace para eliminar carácteres que no necesitemos, etc... es cuestión del contexto en donde se ejecuta la app. En lo persona, PDO y MySQLimp tienen una buena manera para separar la petición con el parámetro que queremos enviar. De esta manera, si nosotros enviamos, i.e pass' OR 1=1 eso siempre será forzado COMO valor del parámetro, por lo que en teoría SELECT * FROM users WHERE pass = ? quedaría SELECT * FROM users WHERE pass = "pass' OR 1=1";.  Si alguien conoce otra idea, adelante, es bueno debatir respecto a como parchar vulnerabilidades.
Cada vez que me das Karma me motivas

Desconectado WilyXem

  • *
  • Underc0der
  • Mensajes: 23
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
« Respuesta #14 en: Enero 27, 2013, 08:48:35 am »
Damn, pues tenias que especificar MySQL improved o injection.
My Twitter: You are not allowed to view links. Register or Login

|| Security Researcher || Little PenTester || Member of UnderC0de.

One day, You gonna find me, I know that - WilyXem's Motto

Desconectado alexander1712

  • *
  • Underc0der
  • Mensajes: 851
  • Actividad:
    0%
  • Reputación -2
    • Ver Perfil
    • El blog del programador
    • Email
« Respuesta #15 en: Enero 27, 2013, 11:59:44 am »
You are not allowed to view links. Register or Login
Alex, pues todo depende del concepto y de la plataforma a la cual quieras evitar inyección SQL. Hay distintas maneras para (NO PARCHAR),  sino para hacer más difícil la tarea de ejecutar ésta. Ya sea con PDO, utilizando expresiones regulares para validar lo que se ingresa, utilizando str_replace para eliminar carácteres que no necesitemos, etc... es cuestión del contexto en donde se ejecuta la app. En lo persona, PDO y MySQLimp tienen una buena manera para separar la petición con el parámetro que queremos enviar. De esta manera, si nosotros enviamos, i.e pass' OR 1=1 eso siempre será forzado COMO valor del parámetro, por lo que en teoría SELECT * FROM users WHERE pass = ? quedaría SELECT * FROM users WHERE pass = "pass' OR 1=1";.  Si alguien conoce otra idea, adelante, es bueno debatir respecto a como parchar vulnerabilidades.

la verdad te agradezco, me haz dado una idea, lo de las expresiones regulares, jamás se me ocurrió utilizarlo de éste modo, porque a decir verdad prefería pensar que con mysql_real_escape_string era suficiente xD es muy interesante lo que propones, como siempre, haz dicho algo muy interesante, no se puede esperar menos de xt3mp.

Citar
Damn, pues tenias que especificar MySQL improved o injection.

mejor dejalo así, peor por la temática y por la forma en que se estaban diciendo las cosas, si sabes del tema, no hacen falta aclaraciones.

en fin, un saludo para todos! y esta es realmente un debate muy interesante, si alguno tiene otras ideas que las comente, siempre y cuando no intente dejar a nadie como tarado, que realmente no aporta en nada.

Desconectado HckDrk

  • *
  • Underc0der
  • Mensajes: 53
  • Actividad:
    0%
  • Reputación 0
  • http://127.0.0.1
    • Ver Perfil
    • HckDrk
« Respuesta #16 en: Enero 27, 2013, 01:16:41 pm »
bueno XD

aquí les dejo unos ejemplos de como se podría evitar con ctype_alnum()

una forma seria eliminando cualquier carácter que no sea alfanumérico...

Código: PHP
  1.        
  2.  
  3.         function limpiar($cadena){
  4.  
  5.         for($i=0;$i<You are not allowed to view links. Register or Login($cadena);$i++){
  6.                 if(You are not allowed to view links. Register or Login($cadena[$i])){
  7.                         $cadena_l.=$cadena[$i];
  8.                 }
  9.         }
  10.  
  11.         return $cadena_l;
  12.         }
  13.  
  14.  
  15. echo "Busqueda de <b>".limpiar($_GET['search'])."</b>";
  16.  

así si intentamos una inyección de esta forma You are not allowed to view links. Register or Login
nos mostraría lo siguiente: "Búsqueda de 1unionselect1"


o simplemente mostramos un mensaje de error


Código: PHP
  1.                 if(You are not allowed to view links. Register or Login($_GET['search'])){
  2.                         echo "Busqueda valida de <b>".You are not allowed to view links. Register or Login($_GET['search'])."</b>"; //ya no haria falta la funcion strip_tags, ya que con ctype_alnum() valida si contiene otros caracteres, sino muestra error, pero es costumbre y no va de mas un poco mas de seguridad XD
  3.                 }else{
  4.                         echo "Error! Busqueda(query, consulta, etc.) invalida!";
  5.                 }
  6.  

asi si introducimos alguna inyección nos mostrara error.

bueno, esta es mi forma en que evitaría un sqli, tal vez no sea la mejor forma, cada quien tiene sus métodos, en fin...

Saludos!  ;D

Desconectado alexander1712

  • *
  • Underc0der
  • Mensajes: 851
  • Actividad:
    0%
  • Reputación -2
    • Ver Perfil
    • El blog del programador
    • Email
« Respuesta #17 en: Enero 27, 2013, 04:12:13 pm »
You are not allowed to view links. Register or Login
bueno XD

aquí les dejo unos ejemplos de como se podría evitar con ctype_alnum()

una forma seria eliminando cualquier carácter que no sea alfanumérico...

Código: PHP
  1.        
  2.  
  3.         function limpiar($cadena){
  4.  
  5.         for($i=0;$i<You are not allowed to view links. Register or Login($cadena);$i++){
  6.                 if(You are not allowed to view links. Register or Login($cadena[$i])){
  7.                         $cadena_l.=$cadena[$i];
  8.                 }
  9.         }
  10.  
  11.         return $cadena_l;
  12.         }
  13.  
  14.  
  15. echo "Busqueda de <b>".limpiar($_GET['search'])."</b>";
  16.  

así si intentamos una inyección de esta forma You are not allowed to view links. Register or Login
nos mostraría lo siguiente: "Búsqueda de 1unionselect1"


o simplemente mostramos un mensaje de error


Código: PHP
  1.                 if(You are not allowed to view links. Register or Login($_GET['search'])){
  2.                         echo "Busqueda valida de <b>".You are not allowed to view links. Register or Login($_GET['search'])."</b>"; //ya no haria falta la funcion strip_tags, ya que con ctype_alnum() valida si contiene otros caracteres, sino muestra error, pero es costumbre y no va de mas un poco mas de seguridad XD
  3.                 }else{
  4.                         echo "Error! Busqueda(query, consulta, etc.) invalida!";
  5.                 }
  6.  

asi si introducimos alguna inyección nos mostrara error.

bueno, esta es mi forma en que evitaría un sqli, tal vez no sea la mejor forma, cada quien tiene sus métodos, en fin...

Saludos!  ;D

si funcionaría bien como int, pero volvamos al ejemplo de una búsqueda que es la misma razon por la que no se puede usar int, si la persona busca con espacios ya no funcionará la busqueda, si la persona busca algo así como los angeles de charly [FULLDVD] tampoco le buscará...

me explico?

para todo lo demás se puede usar la sencilla técnica de elhacker.net que crea urlseo y utiliza el id únicamente (pasado por int) para obtener el registro, mientras que el resto es simplemente decoración o seo.

saludos!

Desconectado 2Fac3R

  • *
  • Underc0der
  • Mensajes: 231
  • Actividad:
    0%
  • Reputación 0
  • Why be a king, when you can be a god
    • Ver Perfil
  • Skype: rockeg_18
« Respuesta #18 en: Enero 27, 2013, 05:35:31 pm »
Ya que están poniendo ejemplos, les dejo unos que tengo desde hace tiempo en PDO:

conexion.php
Código: PHP
  1. <?php
  2.    
  3.     function conectar(){
  4.                 $dsn = 'mysql:host=localhost; dbname=test;';
  5.                 $user = 'root';
  6.                 $pwd = 'toor';
  7.         $con = new PDO($dsn,$user,$pwd);
  8.                
  9.                 return $con;
  10. }
  11. ?>
  12.  

Un pequeño sistema de noticias (muy feo por cierto xD):

Código: PHP
  1. <?php
  2.  
  3. require_once('conexion.php');
  4.  
  5. try{
  6.        
  7.         $con = conectar();
  8.         $id = $_GET['id'];
  9.        
  10.         $query = $con -> prepare("SELECT * FROM noticias WHERE id=:id");
  11.         $query -> bindParam(':id',$id,PDO::PARAM_INT,1);
  12.         $query -> execute();
  13.        
  14.         foreach($query as $value){
  15.                 echo $value['titulo'].'<br>';
  16.                 echo $value['detalle'].'<br>';
  17.                 echo $value['autor'].'<br>';
  18.         }
  19. }catch(PDOException $e){
  20.         You are not allowed to view links. Register or Login($e->getMessage());
  21. }
  22. ?>
  23.  

Podemos expecificar datos, por ejemplo:

PDO::PARAM_STR
PDO::PARAM_INT

You are not allowed to view links. Register or Login

etc..

Zalu2

Desconectado alexander1712

  • *
  • Underc0der
  • Mensajes: 851
  • Actividad:
    0%
  • Reputación -2
    • Ver Perfil
    • El blog del programador
    • Email
« Respuesta #19 en: Enero 27, 2013, 06:50:54 pm »
genial 2Fac3R.

saludos!

 

¿Te gustó el post? COMPARTILO!



Evitar LFI de forma fácil

Iniciado por LucaSthefano

Respuestas: 3
Vistas: 1259
Último mensaje Agosto 01, 2011, 01:49:12 am
por Xt3mP