In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Sql asesino

SQL databases
jose.luis
Posts: 1633
Joined: Fri Oct 14, 2005 10:56 pm

Sql asesino

Postby jose.luis » Sun Jul 15, 2007 8:59 pm

Hola,
Os pongo el siguiente supuesto:
Sea una tabla de clientes donde estamos modificando una ficha.
Hacemos algo parecido a esto:
@ 1,1 GET cNombre PICTURE "@!"
READ
y luego montamos la sentencia SQL para actualizar el dato (por ejemplo):
cSelect := "UPDATE CLIENTES SET Nombre = '"+cNombre+"' WHERE codigo =
'"+cCodigo+"'"
dando como resultado esta sentencia SQL:
UPDATE CLIENTES SET Nombre = 'Nombre del cliente' WHERE codigo = 'micodigo'
Y todo va bien...
Pero... ¿que pasa si en cNombre ponen lo siguiente?
'; DELETE FROM CLIENTES; UPDATE CLIENTES SET Nombre = 'A
Esto da como resultado la siguiente sentencia SQL
UPDATE CLIENTES SET Nombre = ''; DELETE FROM CLIENTES; UPDATE CLIENTES SET
Nombre = 'A' WHERE codigo = 'micodigo'
Ostras!!
Pero... si ponen esto:
'; DROP DATABASE MiBaseDatos; UPDATE CLIENTES SET Nombre = 'A
Nos quedaría una sentencia como esta:
UPDATE CLIENTES SET Nombre = ''; DROP DATABASE MiBaseDatos; UPDATE CLIENTES
SET Nombre = 'A' WHERE codigo = 'micodigo'
Más ostras!!
Saludos,
José Luis Capel
PD: os dejo estos enlaces
http://es.wikipedia.org/wiki/Inyecci%C3%B3n_SQL
http://www.programacionphp.net/recursos-articulos/articulos- de-Vulnerabilidades/SQL-injection_0001601.html
http://www.scourdesign.com/articulos/tutoriales/net/1.php
http://msdn2.microsoft.com/es-es/library/hdb58b2f(VS.80).aspx
jmartial
Posts: 397
Joined: Fri May 20, 2005 8:53 pm

Sql asesino

Postby jmartial » Sun Jul 15, 2007 9:33 pm

Jose,
¿Con qué motor lo has probado?
Yo he probado con Mysql y "se lo traga todo", pero con postgres ese
ejemplo que pones no tendrí­a problemas.
No admite dobles comillas en vez de simple para los literales.
Un Saludo,
Joaquí­n
José Luis Capel escribió:
> Hola,
>
> Os pongo el siguiente supuesto:
>
> Sea una tabla de clientes donde estamos modificando una ficha.
>
> Hacemos algo parecido a esto:
>
> @ 1,1 GET cNombre PICTURE "@!"
> READ
>
> y luego montamos la sentencia SQL para actualizar el dato (por ejemplo):
>
> cSelect := "UPDATE CLIENTES SET Nombre = '"+cNombre+"' WHERE codigo =
> '"+cCodigo+"'"
>
> dando como resultado esta sentencia SQL:
>
> UPDATE CLIENTES SET Nombre = 'Nombre del cliente' WHERE codigo = 'micodigo'
>
> Y todo va bien...
>
> Pero... ¿que pasa si en cNombre ponen lo siguiente?
>
> '; DELETE FROM CLIENTES; UPDATE CLIENTES SET Nombre = 'A
>
> Esto da como resultado la siguiente sentencia SQL
>
> UPDATE CLIENTES SET Nombre = ''; DELETE FROM CLIENTES; UPDATE CLIENTES SET
> Nombre = 'A' WHERE codigo = 'micodigo'
>
> Ostras!!
>
> Pero... si ponen esto:
>
> '; DROP DATABASE MiBaseDatos; UPDATE CLIENTES SET Nombre = 'A
>
> Nos quedarí­a una sentencia como esta:
>
> UPDATE CLIENTES SET Nombre = ''; DROP DATABASE MiBaseDatos; UPDATE CLIENTES
> SET Nombre = 'A' WHERE codigo = 'micodigo'
>
>
> Más ostras!!
>
> Saludos,
> José Luis Capel
> PD: os dejo estos enlaces
> http://es.wikipedia.org/wiki/Inyecci%C3%B3n_SQL
> http://www.programacionphp.net/recursos-articulos/articulos- de-Vulnerabilidades/SQL-injection_0001601.html
> http://www.scourdesign.com/articulos/tutoriales/net/1.php
> http://msdn2.microsoft.com/es-es/library/hdb58b2f(VS.80).aspx
>
>
>
User avatar
jasm
Posts: 447
Joined: Tue Jul 08, 2008 8:12 pm

Sql asesino

Postby jasm » Sun Jul 15, 2007 10:37 pm

Eso se llama SQL Injection en argot de seguridad informática.
Es uno de los ataque mas usados para fastidar bases de datos desde
páginas webs.
Saludos
Jose A. Suarez
notelo
Posts: 54
Joined: Sat Apr 28, 2007 2:06 pm

Sql asesino

Postby notelo » Mon Jul 16, 2007 2:06 pm

José Luis,
la inyección SQL se usa desde hace tiempo para "estropear" bases de datos e
incluso ganar privilegios de administrador en los hosts que las albergan.
Googlea un poco y verás qué fácil es hacerlo contra un blog con algunas
versiones de Wordpress.
Saludos,
José Lalí­n
jose.luis
Posts: 1633
Joined: Fri Oct 14, 2005 10:56 pm

Sql asesino

Postby jose.luis » Mon Jul 16, 2007 3:10 pm

Hola Joaquí­n,
>
> ¿Con qué motor lo has probado?
>
> Yo he probado con Mysql y "se lo traga todo", pero con postgres ese
> ejemplo que pones no tendrí­a problemas.
> No admite dobles comillas en vez de simple para los literales.
>
Creo que no es exclusivo de un motor. Solo hay que cambiar los
delimitadores.
Saludos,
José Luis Capel
jose.luis
Posts: 1633
Joined: Fri Oct 14, 2005 10:56 pm

Sql asesino

Postby jose.luis » Mon Jul 16, 2007 3:16 pm

José Alfonso,
>
> Eso se llama SQL Injection en argot de seguridad informática.
Si... si... ya se lo que es...
>
> Es uno de los ataque mas usados para fastidar bases de datos desde páginas
> webs.
Y en las aplicaciones de escritorio tambien (aunque no tenga ni mucho
sentido ni mucha repercusión).
El caso es que en el improbable caso de que alguno de nuestros clientes
quiera sabotear nuestra aplicación no podremos hacer mucho si se utiliza la
técnica del SELECT, INSERT y UPDATE para acceder, modificar e insertar
datos.
Con ADO la cosa se complica un poco. Si se utilizan los recordsets nativos
de ADO será difí­cil que eso ocurra dado que internamente ADO utiliza
cursores y procedimientos almacenados para actualiar los datos.
Saludos,
José Luis Capel
jose.luis
Posts: 1633
Joined: Fri Oct 14, 2005 10:56 pm

Sql asesino

Postby jose.luis » Mon Jul 16, 2007 3:18 pm

José,
>
> la inyección SQL se usa desde hace tiempo para "estropear" bases de datos
> e incluso ganar privilegios de administrador en los hosts que las
> albergan.
>
> Googlea un poco y verás qué fácil es hacerlo contra un blog con algunas
> versiones de Wordpress.
>
Cierto...
Pero yo quiero trasladarlo a nuestras aplicaciones de escritorio. Se
positivamente que esta situación es altamente improblable que ocurra.
Vamos, no me imagino a un cliente nuestro intentando sabotear sus propios
datos y aplicación.
Saludos,
José Luis Capel
Rolando
Posts: 191
Joined: Mon May 08, 2006 2:10 pm

Sql asesino

Postby Rolando » Mon Jul 16, 2007 4:45 pm

José Luis:
"José Luis Capel" <jose.luis@capelsoft.com> escribió en el mensaje
news:469b7045@ozsrv2.ozlan.local...
> José,
>>
>> la inyección SQL se usa desde hace tiempo para "estropear" bases de datos
>> e incluso ganar privilegios de administrador en los hosts que las
>> albergan.
>>
>> Googlea un poco y verás qué fácil es hacerlo contra un blog con algunas
>> versiones de Wordpress.
>>
>
> Cierto...
>
> Pero yo quiero trasladarlo a nuestras aplicaciones de escritorio. Se
> positivamente que esta situación es altamente improblable que ocurra.
> Vamos, no me imagino a un cliente nuestro intentando sabotear sus propios
> datos y aplicación.
No es dificil imaginarse un empleado enojado con su patron !
Saludos.
>
> Saludos,
> José Luis Capel
Thefull
Posts: 70
Joined: Mon Oct 11, 2004 4:44 pm

Sql asesino

Postby Thefull » Mon Jul 16, 2007 5:05 pm

José Luis Capel escribió:
> Hola Joaquí­n,
>>
>> ¿Con qué motor lo has probado?
>>
>> Yo he probado con Mysql y "se lo traga todo", pero con postgres ese
>> ejemplo que pones no tendrí­a problemas.
>> No admite dobles comillas en vez de simple para los literales.
>>
>
> Creo que no es exclusivo de un motor. Solo hay que cambiar los
> delimitadores.
>
¿ Y si lo pasas a texto ?
Es decir;
UPDATE CLIENTES SET Nombre = ['Nombre del cliente' ] WHERE codigo = [
'micodigo' ]
Lo has probado ?
Saludos
Rafa Carmona
notelo
Posts: 54
Joined: Sat Apr 28, 2007 2:06 pm

Sql asesino

Postby notelo » Mon Jul 16, 2007 7:21 pm

José Luis,
> Pero yo quiero trasladarlo a nuestras aplicaciones de escritorio. Se
> positivamente que esta situación es altamente improblable que ocurra.
> Vamos, no me imagino a un cliente nuestro intentando sabotear sus
> propios datos y aplicación.
Puede que te fí­es del cliente pero no sabes a quién tiene trabajando para
él o quién tiene acceso a sus datos.
Según he leí­do una de las mejores maneras de evitar esto es analizar el
texto introducido (comprobar número de comillas, si contiene mandatos que
no deberí­a como DROP, etc.) antes de montar la sentencia SQL, siempre en
caso de que permitas escribirlas desde la aplicación o las guardes en algún
archivo.
Saludos,
José Lalí­n
jose.luis
Posts: 1633
Joined: Fri Oct 14, 2005 10:56 pm

Sql asesino

Postby jose.luis » Mon Jul 16, 2007 8:16 pm

José,
>
> Puede que te fí­es del cliente pero no sabes a quién tiene trabajando para
> él o quién tiene acceso a sus datos.
>
> Según he leí­do una de las mejores maneras de evitar esto es analizar el
> texto introducido (comprobar número de comillas, si contiene mandatos que
> no deberí­a como DROP, etc.) antes de montar la sentencia SQL, siempre en
> caso de que permitas escribirlas desde la aplicación o las guardes en
> algún archivo.
Yo estoy cambiando todos los acceso a base de datos. Actualmente estoy
utilizando ADO (con clases propias) contra un SQL Server. He visto dos
posibles situaciones:
a. Utilizar un Recordset de ADO lado servidor. En este caso ADO crea un
cursor y lo actualiza con procedimientos almacenados. Si utilizamos un
recordset de lado cliente entonces no hay cursor abierto, pero sigue
actualizando los datos con un procedimiento almacenado. Este caso es el más
favorable dado que la inyección de código malicioso nunca llegará a
ejecutarse. Como mucho ocurrirá un error en la ejecución del procedimiento.
b. Utilizar directamente el método execute del objeto connection. Este es
el peor caso. Es ahí­ donde se nos puede colar el código sql malicioso.
El primer caso ya me lo resuelve ADO. Para el segundo caso estoy cambiando
paulatinamente mis llamadas directas por llamadas a través de un
procedimiento almacenado.
Sql Server provee un procedimiento almacenado que te permite lanzar tu
sentencia SQL. El procedimiento en cuestión es el sp_executesql.
Entiendo que 'monitorizar' cada una de las sentencias sql mediante un
diccionario puede ralentizar procesos con llamadas intensivas o, si no está
bien implementado, dar falsos 'positivos'.
Saludos,
José Luis Capel
jose.luis
Posts: 1633
Joined: Fri Oct 14, 2005 10:56 pm

Sql asesino

Postby jose.luis » Mon Jul 16, 2007 8:17 pm

Rafa,
> ¿ Y si lo pasas a texto ?
> Es decir;
> UPDATE CLIENTES SET Nombre = ['Nombre del cliente' ] WHERE codigo = [
> 'micodigo' ]
> Lo has probado ?
Si... me coloca los ' como parte de la cadena.
Saludos,
José Luis Capel
Thefull
Posts: 70
Joined: Mon Oct 11, 2004 4:44 pm

Sql asesino

Postby Thefull » Tue Jul 17, 2007 9:41 am

José Luis Capel escribió:
> Rafa,
>> ¿ Y si lo pasas a texto ?
>> Es decir;
>> UPDATE CLIENTES SET Nombre = ['Nombre del cliente' ] WHERE codigo = [
>> 'micodigo' ]
>> Lo has probado ?
>
> Si... me coloca los ' como parte de la cadena.
>
Entonces, si lo montas de esta manera;
'UPDATE CLIENTES SET Nombre =" '+ cNombre + ' " WHERE codigo = "' +
cCodigo +'"'
Nombre = "DROP DATABASE;" , eso NO DEBERIA DE EJECUTARSE! simplemente
meterá el comando como nombre.
Saludos
Rafa Carmona
notelo
Posts: 54
Joined: Sat Apr 28, 2007 2:06 pm

Sql asesino

Postby notelo » Tue Jul 17, 2007 5:08 pm

José,
creo que la respuesta anterior es digna de ser elaborada un poco más y se
merece un post en tu blog.
Saludos,
José Lalí­n
jose.luis
Posts: 1633
Joined: Fri Oct 14, 2005 10:56 pm

Sql asesino

Postby jose.luis » Tue Jul 17, 2007 8:46 pm

José,
>
> creo que la respuesta anterior es digna de ser elaborada un poco más y se
> merece un post en tu blog.
>
El blog lo tengo 'cerrado' por falta de tiempo. A ver si en los dí­as de
vacaciones puedo hacer alguna cosilla.
Saludos,
José Luis Capel
User avatar
jfgimenez
Site Admin
Posts: 5629
Joined: Mon Apr 06, 2015 8:48 pm
Contact:

Sql asesino

Postby jfgimenez » Tue Jul 17, 2007 9:25 pm

José Luis,
creo que hay una forma muy sencilla de evitar este tipo de 'SQL injection':
comprobar si hay algún carácter de punto y coma (;) en la sentencia. Si lo
hay, entonces casi seguro que se trata de un 'SQL injection'.
Eso sí, desde programa hay que renunciar a escribir varias sentencias en una
misma llamada, pero no creo que eso sea problema en la mayoría de los casos.
O simplemente se puede tener una función que detecte ese carácter, y no
llamarla cuando se quiera hacer.
Por otro lado, imagino que hay más tipos de 'SQL injection', pero supongo
que este es el principal y el más común.
Por cierto, con SQLite no funciona, ya que cuando encuentra un ; en una
sentencia, ejecuta lo que hay antes e ignora lo que sigue.
--
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
User avatar
jasm
Posts: 447
Joined: Tue Jul 08, 2008 8:12 pm

Sql asesino

Postby jasm » Tue Jul 17, 2007 9:28 pm

Jose,
> José Luis,
>
> creo que hay una forma muy sencilla de evitar este tipo de 'SQL injection':
> comprobar si hay algún carácter de punto y coma (;) en la sentencia. Si lo
> hay, entonces casi seguro que se trata de un 'SQL injection'.
Difí­cil implementación por aquello de que cada vez más incluimos campos
de texto grandes para tomar notas donde los usuarios pueden incluir
cualquier carácter, incluido el punto y coma (;).
Saludos
Jose A. Suarez
User avatar
jfgimenez
Site Admin
Posts: 5629
Joined: Mon Apr 06, 2015 8:48 pm
Contact:

Sql asesino

Postby jfgimenez » Tue Jul 17, 2007 9:43 pm

José Alfonso,
> Difícil implementación por aquello de que cada vez más incluimos campos de
> texto grandes para tomar notas donde los usuarios pueden incluir cualquier
> carácter, incluido el punto y coma (;).
Sí, por supuesto. Lo que hay que buscar es el ; fuera de cualquier cadena de
texto. El ejemplo que ha puesto José Luis termina con la sentencia:
UPDATE CLIENTES SET Nombre = ''; DELETE FROM CLIENTES; UPDATE CLIENTES SET
Nombre = 'A' WHERE codigo = 'micodigo'
Si te fijas, los ; están fuera de las cadenas, y eso es muy fácil
detectarlo.
--
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
User avatar
jfgimenez
Site Admin
Posts: 5629
Joined: Mon Apr 06, 2015 8:48 pm
Contact:

Sql asesino

Postby jfgimenez » Tue Jul 17, 2007 10:12 pm

Hola,
aquí teneis una función en C muy sencilla para comprobar este caso:
//---------------------------------------------------------- --------------------
XA_FUNC( CHECKSQLINJECTION )
{
char *cSql = hb_parc( 1 ), c;
int lString = FALSE;
int lInjection = FALSE;
while( c = *cSql++ )
{
if( c == ''' )
lString = !lString;
else if( ( c == ';' ) && ( !lString ) )
{
lInjection = TRUE;
break;
}
}
hb_retl( lInjection );
}
//---------------------------------------------------------- ----------------
Simplemente se le pasa la sentencia SQL y devuelve .T. si se trata de un
'SQL injection', o .F. si todo está correcto.
--
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
jose.luis
Posts: 1633
Joined: Fri Oct 14, 2005 10:56 pm

Sql asesino

Postby jose.luis » Tue Jul 17, 2007 11:56 pm

José,
>
> Sí­, por supuesto. Lo que hay que buscar es el ; fuera de cualquier cadena
> de texto. El ejemplo que ha puesto José Luis termina con la sentencia:
>
> UPDATE CLIENTES SET Nombre = ''; DELETE FROM CLIENTES; UPDATE CLIENTES SET
> Nombre = 'A' WHERE codigo = 'micodigo'
>
> Si te fijas, los ; están fuera de las cadenas, y eso es muy fácil
> detectarlo.
Ya... pero en SqlServer puedes no colocar ; como separador de instrucciones.
Puedes poner GO o incluso nada.
Creo que lo más efectivo serí­a utilizar procedimientos almacenados para
lanzar nuestras consultas al servidor. Como he comentado en otro mensaje de
este hilo, SqlServer provee de un procedimiento almacenado especializado
para la ejecución de sentencias sql. Este procedimiento tiene una ventaja
adicional que es el hecho de que ante consultas repetitivas funciona más
rápido dado que el servidor las 'precompila'. No tengo claro si MySql tiene
algo parecido.
Saludos,
José Luis Capel
Saludos,
José Luis Capel
jose.luis
Posts: 1633
Joined: Fri Oct 14, 2005 10:56 pm

Sql asesino

Postby jose.luis » Wed Jul 18, 2007 9:38 am

José,
> Sí, por supuesto. Lo que hay que buscar es el ; fuera de cualquier cadena
> de texto. El ejemplo que ha puesto José Luis termina con la sentencia:
>
> UPDATE CLIENTES SET Nombre = ''; DELETE FROM CLIENTES; UPDATE CLIENTES SET
> Nombre = 'A' WHERE codigo = 'micodigo'
>
Creo que esta forma no es ágil. En muchos casos utilizo varias sentencias
en la misma consulta. Básicamente el uso de SETS.
Saludos,
José Luis Capel
User avatar
jfgimenez
Site Admin
Posts: 5629
Joined: Mon Apr 06, 2015 8:48 pm
Contact:

Sql asesino

Postby jfgimenez » Wed Jul 18, 2007 11:41 am

José Luis,
>> Sí, por supuesto. Lo que hay que buscar es el ; fuera de cualquier cadena
>> de texto. El ejemplo que ha puesto José Luis termina con la sentencia:
>>
>> UPDATE CLIENTES SET Nombre = ''; DELETE FROM CLIENTES; UPDATE CLIENTES
>> SET
>> Nombre = 'A' WHERE codigo = 'micodigo'
>>
>
> Creo que esta forma no es ágil. En muchos casos utilizo varias sentencias
> en la misma consulta. Básicamente el uso de SETS.
Bueno, por ahora ya está puesto en Xailer en los dataset de MySQL. Si se
utiliza directamente Execute(), no se comprueba nada, y puedes poner todas
las sentencias que quieras. Pero en los dataset, que están orientados al
manejo de tablas individuales (los de lectura-escritura), las sentencias las
genera el propio dataset, y es ahí donde hemos metido esta protección. Así,
si un 'usuario espabilado' se le ocurre poner alguna perla de las que has
comentado en el nombre de un cliente, p.ej., ya no puede hacer esos
destrozos.
--
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
jose.luis
Posts: 1633
Joined: Fri Oct 14, 2005 10:56 pm

Sql asesino

Postby jose.luis » Thu Jul 19, 2007 8:37 pm

José,
Estupendo!! Es una buena noticia.
>
> Bueno, por ahora ya está puesto en Xailer en los dataset de MySQL. Si se
> utiliza directamente Execute(), no se comprueba nada, y puedes poner todas
> las sentencias que quieras. Pero en los dataset, que están orientados al
> manejo de tablas individuales (los de lectura-escritura), las sentencias
> las genera el propio dataset, y es ahí­ donde hemos metido esta protección.
> Así­, si un 'usuario espabilado' se le ocurre poner alguna perla de las que
> has comentado en el nombre de un cliente, p.ej., ya no puede hacer esos
> destrozos.
Solo una puntualización:
Creo que el proceso de comprobación de código asesino deberí­a anular ese
código en vez de invalidar sentencia (no se si es tu caso). Desde mi punto
de vista creo que deberí­a sustituir los caracteres potencialmente peligrosos
por otros que neutralicen la acción dañina.
Por ejemplo:
SELECT * FROM clientes WHERE clicodi = 'M'; DROP TABLE mitabla
Sustituirlo por ;
SELECT * FROM clientes WHERE clicodi = 'M' /* DROP TABLE mitabla
Saludos,
José Luis Capel

Return to “SQL”