Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Temas relacionados > Seguridad
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 04-12-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Creo que hay un problemita dec. Digamos que tu consulta es

Código SQL [-]
select * from usuarios where usuario = 'pepe el toro'

Al aplicarle la función Escapar queda así:

Código SQL [-]
select * from usuarios where usuario=\'pepe el toro\'

Y esto no lo acepta MySql.

// Saludos
Responder Con Cita
  #2  
Antiguo 04-12-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

No. En realidad no se le aplica "Escapar" a la consulta SQL, sino a los elementos que la conforman.

Es decir, no se hace algo como esto:

Código PHP:
$titulo $_POST['titulo'];
$consultaSql Escapar("SELECT * FROM enlaces WHERE titulo = '$titulo'"); 
Sino que se hace algo como esto otro:

Código PHP:
$titulo Escapar($_POST['titulo']);
$consultaSql Escapar("SELECT * FROM enlaces WHERE titulo = '$titulo'"); 
Sigo el manual de PHP, la función: mysql_real_escape_string, concretamente el ejemplo número 2: "An example SQL Injection Attack".
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 04-12-2006 a las 19:15:36.
Responder Con Cita
  #3  
Antiguo 04-12-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Por cierto, el método "Escapar" de la clase XHtml va por estos derroteros por el momento...

Código PHP:
  function Escapar($entrada) {
      return 
htmlentities(strip_tags
       
(stripslashes($entrada)), ENT_QUOTES'utf-8');    
  } 
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #4  
Antiguo 05-12-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Bueno... pues ya estoy más tranquilo (acabo de suspirar y todo, no te digo yo que...). Menudo repaso le he pegado al asunto (léase Loturak - ¡ajá!). Lo bueno y lo malo de estas cosas es que no ves errores que los tienes ahí en tus narices... y que luego aparecen como por arte de magia. He solucionado no pocos errores o potenciales problemas (¿los llamaré "bugs"?) mientras andaba con el tema de los "escapes"...

Por otro lado creo que me ha quedado claro para siempre lo que he comentado más arriba: una cosa es el "escape" por el que tiene que pasar variable que luego tiene que pasar por una consulta SQL, y otra cosa es el "escape" que tiene que pasar una variable que luego imprimiremos en el código HTML de la página Web de turno. Si hubiera estado con más proyectos además de Loturak estoy seguro de que el problema se hubiera producido en todos ellos.


El "escape" de variables para consultas SQL

Supongamos algo como esto:

Código PHP:
 
 $titulo 
'';
 if(isset(
$_GET['titulo']))
   
$titulo $_GET['titulo'];
 
 
$consultaSql "SELECT * FROM enlaces WHERE titulo = '$titulo';"
Lo que entiendo ahora como correcto queda tal que así:

Código PHP:
 
 $titulo 
'';
 if(isset(
$_GET['titulo']))
   
$titulo $bdatos->Escapar($_GET['titulo']);
 
 
$consultaSql "SELECT * FROM enlaces WHERE titulo = '$titulo';"
Y el método "Escapar" utilizado es:

Código PHP:

function Escapar($cadena) {
  if(
get_magic_quotes_gpc()) $cadena stripslashes($cadena);        
    return 
mysql_real_escape_string($cadena$this->enlaceConexionBd);

Con eso, según el manual de PHP estamos evitando un posible "ataque SQL Injection" de esos... que haberlos haylos, que me lo han dicho a mí.

No sigo el manual al dedillo en mi caso, puesto que según se dice en el mismo "la mejor forma de hacer esto es":

Código PHP:
function quote_smart($value)
{
    
// Stripslashes
    
if (get_magic_quotes_gpc()) {
        
$value stripslashes($value);
    }
    
// Quote if not a number or a numeric string
    
if (!is_numeric($value)) {
        
$value "'" mysql_real_escape_string($value) . "'";
    }
    return 
$value;

Es muy probable que acabe utilizando algo así. Si no lo hago ahora es porque las consultas SQL acostumbro a realizarlas incluyendo por mi cuenta las comillas "simples" para valores de tipo "cadena" y no incluirlas para valores de tipo numérico: por lo demás, ambos métodos de escape son iguales. De hecho yo me copié del manual.

Nótese, sin embargo, que el método de escape no valida la entrada del usuario, es decir, se limita a escapar determinados caracteres para impedir el SQL Injection. Para validar la entrada del usuario debemos contar con las correspondientes reglas, que tendremos que aplicar por nuestra cuenta. Es decir, el código anterior quedaría algo así:


Código PHP:
  
  $titulo 
'';
  if(isset(
$_GET['titulo']))
    
$titulo $bdatos->Escapar($_GET['titulo']);
  
if(!
ValidarTitulo($titulo))
{
  
MostrarError();  
  die;
}
else
{
  
$consultaSql "SELECT * FROM enlaces WHERE titulo = '$titulo';";
  
EjecutarConsulta($consultaSql);
  } 
Pero creo que puede verse más claro de este modo:

Código PHP:
   
   $titulo 
'';
   if(isset(
$_GET['titulo']))
     
$titulo $bdatos->Escapar($_GET['titulo']);
   
 if(!
ValidarTitulo($titulo))
 {
   
MostrarError();  
   die;
 }
 else
 {
   
$consultaSql "INSERT INTO enlaces (titulo) VALUES('$titulo');";
   
EjecutarConsulta($consultaSql);
   } 
Es decir, no aceptaremos en la base de datos enlaces que no cumplan determinadas reglas, sea que miremos por la longitud (en caracteres) del título, sea que reviremos que no contenga determinados caracteres, etc.

Así que como puede verse una cosa no excluye a la otra. Se escapan las variables que van a entrar a formar parte de una consulta SQL. Se valida la entrada del usuario siguiendo las reglas que consideremos oportunas. No son cosas iguales... aunque a mí me lo pareciera hasta anteayer.


El "escape" de variables que van a imprimirse en el HTML

Este tema es curioso. O a mí me lo parece, vamos. Ya visteis cómo la segunda URL que puso el compañero que informó del problema en Loturak conseguía introducir un "evento JavaScript" en un determinado elemento HTML.

Lo que más me llamó la atención (aunque no intuía aún la posible solución) es que el "problema" no se daba sólo con la URL que el compañero propuso, sino que ocurría también en todas las casillas de todos los formularios de la aplicación...

Más tarde descubrí que ni siquiera eso... el problema se daba en más sitios que en las casillas de los formularios, pero, en ambos casos estábamos hablando de lo mismo.

Cuando nos llegan variables vía GET, por ejemplo, y estas van a imprimirse en el código HTML de la página Web también hay que "escaparlas", pues, aunque ya sabemos que no estamos hablando del mismo tipo de "escape" que arriba comentamos para las consultas SQL.

Código PHP:

function Escapar($entrada
{
  return 
htmlentities(strip_tags
   
(stripslashes($entrada)), 
    
ENT_QUOTES'utf-8');    

El "atacante" puede hacer virgerías... así que aplicamos determinados filtros a la entrada (del usuario) para tratar de "paliar" las consecuencias o eliminarlas del todo... si se puede.

Con las funciones de que se compone nuestra función "Escapar" tratamos de convertir algunos caracteres especiales de HTML a su entidad correspondiente. Por ejemplo, sustituimos los "&" por "&". A continuación eliminamos de la variable "entrada" las etiquetas HTML y PHP que pudiera contener. Y para terminar eliminamos los "\" de la entrada.

Todo esto para evitar, por ejemplo, que recibamos en una variable de entrada algo como esto:

Código:
demo" onmouseover=alert(123) "
Si no escapáramos esa entrada y la misma terminara imprimiéndose tal cual en el código HTML de la página Web tendríamos algo como esto:

Código:
<input name="b" value="demo\" onmouseover=alert(123) \"" type="text" id="casillabusqueda" class="inputtext" />
Es decir, que cuando el usuario pasara el ratón por la casilla de búsqueda, en este caso, iba a recibir un pequeño susto....

¿Qué ocurre cuando se escapa la cadena de entrada con el método anteriormente visto? Algo bastante distinto, gracias, en este caso más que nada, a la función "htmlentities":

Código:
<input name="b" value="demo&quot; onmouseover=alert(123) "" id="casillabusqueda" class="inputtext" type="text">
De ese modo le mostramos al usuario lo que realmente ha buscado... pero, principalmente impedimos que el evento que trataba de introducirse surta efecto alguno.

Ahora bien. Lo curioso del asunto es que este tipo de escape no se ciñe sólo variables que nos llegan vía HTTP GET, por ejemplo. Supongamos una aplicación que permita a sus usuarios guardar datos de sus enlaces favoritos (¡ajá!).

Supongamos que alguien introduce como título de un enlace la cadena anterior. Puede que sea válida, es decir, puede que la aplicación considere que esa cadena resulta válida como título de un enlace: cumple con las reglas.

Pero, en cuanto esa cadena se introduzca como título de un enlace tendremos el problema multiplicado por la aplicación... en todo lugar en que se muestre el enlace del usuario puede terminar ocurriendo que "el evento JavScript" funcione... no sólo en las casillas de los formularios, sino en cualquier otra parte.

Precisamente, en cualquier otra parte en que se muestre el título del enlace... porque lo mismo da esto:

Código:
<input name="b" value="demo\" onmouseover=alert(123) \"" type="text" id="casillabusqueda" class="inputtext" />
Que esto otro:

Código:
<li name="b" title="demo\" onmouseover=alert(123) \"" />
El evento se añadirá esta vez en la lista en la que mostramos una serie de enlaces, por ejemplo. Como cada elemento de la lista muestra el título del enlace y el título del enlace contiene el "código malicioso"... pues eso.

Es decir, ya no recibimos la cadena "peligrosa" y a escapar desde la entrada del usuario, bueno, sí, pero, esta puede estar ya en nuestra base de datos... porque, como he dicho, la cadena anterior puede ser válida como título de un enlace y será guardada en la base de datos religiosamente... y cada vez que la precisemos mostrar en el código HTML de la aplicación tendremos problemas...

Mejor dicho tendríamos problemas. Y es que si procuramos escapar este tipo de variables con la función de más arriba, aparentemente, al menos, se acabaron las disputas en ese sentido al menos.

No es que haya que escapar todos los datos de un enlace (siguiendo con el ejemplo, para hacerme entender). Por ejemplo, si en nuestra tabla de enlaces guardamos el ID, el título y la URL de un enlace,... lo que puede resultar "peligroso" es el título y la URL, precisamente, porque es el usuario quien determina el título y la URL de los enlaces. Como el ID es un dato en el que no interviene el usuario no es necesario que lo escapemos. Y quien dice el ID dice la fecha del enlace, el número de visitas, etc., cualquier dato que el usuario no pueda editar.


Conclusiones

Dicho todo esto, se entenderá porqué tenía los problemas que tenía en la Web que me traigo entre manos: estaba utilizando el mismo método "Escapar" para todo... entradas de usuario, datos de la base de datos, variables para consultas SQL... para todo usaba el mismo método, además no del todo en condiciones... ¿cómo iba a ir la cosa? Pues mal.

Así que agradezco un montón a quien se molestó en informarme de este problema. Creo que me ha quedado lo suficientemente claro el asunto como para andarme con ojo en la aplicación de aquí en adelante y saber por dónde ando en este sentido. Muchas gracias también a todos cuantos colaborásteis de algún modo.

Y ya está. Eso es todo. Disculpad el rollo, y, si tenéis cualquier cosa que decir respecto a lo dicho aquí no dejéis de hacerlo, por favor. Cualquier comentario, sugerencia, crítica, correción, todo será bienvenido.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #5  
Antiguo 05-12-2006
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Pues reitero lo dicho. Estupendo compendio. Y sobre todo, muestra que además yo estaba equivocado al pensar que podía no ser peligroso el segundo tipo de ataque que te advirtieron.

Muchas gracias por aclararnos esto a todos.

// Saludos
Responder Con Cita
  #6  
Antiguo 05-12-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Gracias siempre a vosotros Román. Yo creo que el mismo nombre "Cross Site Scripting" quiere decir "cuidado, porque pueden en tu Script código que se ejecute en tu Script, pero que venga de fuera...". La cosa es el juego que puede dar esto. Yo creo que desde luego puede dar mucho más juego que mostrar una alerta al usuario.

Desde luego que hacer "otras cosas" no será a lo mejor tan sencillo de "pasar" que el "alert", pero, si se consigue pasar el "alert" puede que ya sea indicio suficiente como para ir más allá. Desde luego hay que tener ganas de hacerlo, saber hacerlo y ponerse a hacerlo. Yo en esto es pez.

Pero, ya digo, intuyo (por el nombre que se le da al asunto) que la cosa puede resultar: al fin y al cabo es una inyección de código, es decir, se está incluyendo código que se ejecutará en "el entorno" de tu página, acaso con ciertos privilegios, precisamente por eso, y es código que viene de fuera y puede que con malas intenciones...

Yo imagino (desde mi desconocimiento) algo así como si se consiguiera incluir un Script PHP que tu página procesase. Pienso en herramientas que ayudan a realizar el "backup" de una base de datos: este tipo de programas suelen necesitar que tú incluyas determinado código en tu Script, de manera que dicho código se procese en tu Servidor, más aún, precisamente por eso, porque si no es desde tu Servidor no pueden llevar a cabo determinadas tareas.

Pues por ahí van los tiros. ¿No?
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #7  
Antiguo 26-12-2006
warpmaster warpmaster is offline
Registrado
 
Registrado: dic 2006
Posts: 1
Poder: 0
warpmaster Va por buen camino
Hilo muy interesante

Hola a todos!

Soy nuevo por estos lares. Llegué utilizando al sr. Google cuando buscaba información sobre escapar código html en comentarios y tal.

La verdad es que el hilo es muy interesante, claro y conciso. No se hasta que punto es importante estas modificaciones pero no está demás.

En mi caso, había empleado en mi web un senzillo buscador que empleaba una sentencia usando el LIKE '%xxxx' y bueno, lo que leí me pareció justificar los minutos que había que emplear en hacer ese par de cambios. ¿Se puede llegar a hacer SQL injection con un sólo campo de formulario, como en mi caso?No lo se.

En todo caso, gracias por la información!!!

Saludos
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Pivot table Editable (cross-tab) villegasmajano MS SQL Server 1 25-10-2006 23:28:57
como manejan uds en Firebird 1.5 el PIVOT de oracle?? (CROSS TABS) pvizcay Firebird e Interbase 4 19-09-2006 19:17:32
Ajuste de decimales en un Cross-Tab nugame Impresión 4 16-06-2004 13:40:44


La franja horaria es GMT +2. Ahora son las 23:47:15.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi