Inyeccion de codigo

17/03/2005 - 18:37 por Infoliber | Informe spam
Hola,
mirando el help me parecio que para que no me pudieran inyectar codigo
desde un campo de consulta era mejor poner storedprocedures.

He empezado una aplicacion en asp.net y todas las consultas las hago con
storedProcedures pero no veo el motivo por el cual se evita la inyeccion de
codigo, si yo le paso a un parametro una parte de codigo este se pasa al sql
server, lo veo igual que hacer la consulta sin los storedProcedures.

¿Como se puede evitar la inyeccion de codigo?

Gracias

Preguntas similare

Leer las respuestas

#6 Alejandro Mesa
18/03/2005 - 16:01 | Informe spam
Maxi,

Esto es cuando generas la sentencia dinamicamente en la aplicacion cliente.
Esto es peor, no solo debes chequear la inyeccion de codigo, sino que si
debes arreglar algo o cambiarlo, debes buscar por cuanta aplicacion tengas.


AMB


"Maxi" wrote:

Hola mi amigo, te paso un articulo de Miguel Egea donde muestra algunas
cosas de las que te comente ;)

http://www.configuracionesintegrale...p?articulo4

prometo buscarte algo mas especifico en cuento a los parametros de los sp's
:-)


Salu2
Maxi


"Alejandro Mesa" escribió en el
mensaje news:
> Hombre, donde has estado?
>
>> Ojo ALe, hay veces que un SP puede tener un param varcghar(300) y ya ahi
>> puedes injectar mucho codigo aunque no lo creas, y no es necesario usar
>> sql-dinamico para que esto suceda
>
> No se me ocurre como, pudieras exponernos un ejemplo?
>
>
> AMB
>
>
>
>
> "Maxi" wrote:
>
>> Ojo ALe, hay veces que un SP puede tener un param varcghar(300) y ya ahi
>> puedes injectar mucho codigo aunque no lo creas, y no es necesario usar
>> sql-dinamico para que esto suceda
>>
>>
>> Salu2
>> Maxi
>>
>>
>> "Alejandro Mesa" escribió en el
>> mensaje news:
>> > Una forma de evitar inyeccion atraves de los sp es el tipo de dato de
>> > los
>> > parametros. Si declaras @par1 como INT entonces que vas a inyectar?.
>> > Tambien
>> > si el parametro es por ejemplo char(3), pues no podras inyectar mucho
>> > que
>> > digamos. El problema estaria en aquellos sp que usan sql dinamico y
>> > esperan
>> > parametros con tipo de datos char / nchar/ varchar / etc., y para poder
>> > inyectar codigo habria que de alguna manera cerrar la cadena.
>> >
>> > Ejemplo:
>> >
>> > use northwind
>> > go
>> >
>> > alter procedure proc1
>> > @par1 nvarchar(40)
>> > as
>> > set nocount on
>> >
>> > declare @sql nvarchar(4000)
>> >
>> > set @sql = N'
>> > select *
>> > from customers
>> > where companyname = ''' + @par1 + ''''
>> >
>> > print @sql
>> > exec sp_executesql @sql
>> > go
>> >
>> > create table t(colA int)
>> > go
>> >
>> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> > go
>> >
>> > select * from t
>> > go
>> >
>> > Fijate en la sentencia que se armo dinamicamente.
>> >
>> > Puedes hacer lo siguiente, si vas a usar sql dinamico. Usar
>> > sp_executesql
>> > y
>> > no EXEC(), usar parametros en el procedimiento sp_executesql o duplicar
>> > todos
>> > los apostrofes dentro del parametro pasado.
>> >
>> > alter procedure proc1
>> > @par1 nvarchar(40)
>> > as
>> > set nocount on
>> >
>> > declare @sql nvarchar(4000)
>> >
>> > set @sql = N'
>> > select *
>> > from customers
>> > where companyname = ''' + replace(@par1, '''', '''''') + ''''
>> >
>> > print @sql
>> > exec sp_executesql @sql
>> > go
>> >
>> > create table t(colA int)
>> > go
>> >
>> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> > go
>> >
>> > select * from t
>> > go
>> >
>> > drop table t
>> > go
>> >
>> > alter procedure proc1
>> > @par1 nvarchar(40)
>> > as
>> > set nocount on
>> >
>> > declare @sql nvarchar(4000)
>> >
>> > set @sql = N'
>> > select *
>> > from customers
>> > where companyname = @par1'
>> >
>> > print @sql
>> > exec sp_executesql @sql, N'@par1 nvarchar(40)', @par1
>> > go
>> >
>> > create table t(colA int)
>> > go
>> >
>> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> > go
>> >
>> > select * from t
>> > go
>> >
>> > drop table t
>> > go
>> >
>> >
>> > AMB
>> >
>> > "Infoliber" wrote:
>> >
>> >> Hola,
>> >> mirando el help me parecio que para que no me pudieran inyectar
>> >> codigo
>> >> desde un campo de consulta era mejor poner storedprocedures.
>> >>
>> >> He empezado una aplicacion en asp.net y todas las consultas las hago
>> >> con
>> >> storedProcedures pero no veo el motivo por el cual se evita la
>> >> inyeccion
>> >> de
>> >> codigo, si yo le paso a un parametro una parte de codigo este se pasa
>> >> al
>> >> sql
>> >> server, lo veo igual que hacer la consulta sin los storedProcedures.
>> >>
>> >> ¿Como se puede evitar la inyeccion de codigo?
>> >>
>> >> Gracias
>> >>
>> >>
>> >>
>>
>>
>>



Respuesta Responder a este mensaje
#7 Maxi
18/03/2005 - 16:19 | Informe spam
Si ya se, pero no me entendiste creo. Proba de armar un Sp's y usar las ' y
veras las maravillas que puedes hacer :)

Lo que te queria decir que no alcanza solo con usar SP, sino que tambien hay
que controlar como vienen los datos.


Salu2
Maxi


"Alejandro Mesa" escribió en el
mensaje news:
Maxi,

Esto es cuando generas la sentencia dinamicamente en la aplicacion
cliente.
Esto es peor, no solo debes chequear la inyeccion de codigo, sino que si
debes arreglar algo o cambiarlo, debes buscar por cuanta aplicacion
tengas.


AMB


"Maxi" wrote:

Hola mi amigo, te paso un articulo de Miguel Egea donde muestra algunas
cosas de las que te comente ;)

http://www.configuracionesintegrale...p?articulo4

prometo buscarte algo mas especifico en cuento a los parametros de los
sp's
:-)


Salu2
Maxi


"Alejandro Mesa" escribió en el
mensaje news:
> Hombre, donde has estado?
>
>> Ojo ALe, hay veces que un SP puede tener un param varcghar(300) y ya
>> ahi
>> puedes injectar mucho codigo aunque no lo creas, y no es necesario
>> usar
>> sql-dinamico para que esto suceda
>
> No se me ocurre como, pudieras exponernos un ejemplo?
>
>
> AMB
>
>
>
>
> "Maxi" wrote:
>
>> Ojo ALe, hay veces que un SP puede tener un param varcghar(300) y ya
>> ahi
>> puedes injectar mucho codigo aunque no lo creas, y no es necesario
>> usar
>> sql-dinamico para que esto suceda
>>
>>
>> Salu2
>> Maxi
>>
>>
>> "Alejandro Mesa" escribió en
>> el
>> mensaje news:
>> > Una forma de evitar inyeccion atraves de los sp es el tipo de dato
>> > de
>> > los
>> > parametros. Si declaras @par1 como INT entonces que vas a inyectar?.
>> > Tambien
>> > si el parametro es por ejemplo char(3), pues no podras inyectar
>> > mucho
>> > que
>> > digamos. El problema estaria en aquellos sp que usan sql dinamico y
>> > esperan
>> > parametros con tipo de datos char / nchar/ varchar / etc., y para
>> > poder
>> > inyectar codigo habria que de alguna manera cerrar la cadena.
>> >
>> > Ejemplo:
>> >
>> > use northwind
>> > go
>> >
>> > alter procedure proc1
>> > @par1 nvarchar(40)
>> > as
>> > set nocount on
>> >
>> > declare @sql nvarchar(4000)
>> >
>> > set @sql = N'
>> > select *
>> > from customers
>> > where companyname = ''' + @par1 + ''''
>> >
>> > print @sql
>> > exec sp_executesql @sql
>> > go
>> >
>> > create table t(colA int)
>> > go
>> >
>> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> > go
>> >
>> > select * from t
>> > go
>> >
>> > Fijate en la sentencia que se armo dinamicamente.
>> >
>> > Puedes hacer lo siguiente, si vas a usar sql dinamico. Usar
>> > sp_executesql
>> > y
>> > no EXEC(), usar parametros en el procedimiento sp_executesql o
>> > duplicar
>> > todos
>> > los apostrofes dentro del parametro pasado.
>> >
>> > alter procedure proc1
>> > @par1 nvarchar(40)
>> > as
>> > set nocount on
>> >
>> > declare @sql nvarchar(4000)
>> >
>> > set @sql = N'
>> > select *
>> > from customers
>> > where companyname = ''' + replace(@par1, '''', '''''') + ''''
>> >
>> > print @sql
>> > exec sp_executesql @sql
>> > go
>> >
>> > create table t(colA int)
>> > go
>> >
>> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> > go
>> >
>> > select * from t
>> > go
>> >
>> > drop table t
>> > go
>> >
>> > alter procedure proc1
>> > @par1 nvarchar(40)
>> > as
>> > set nocount on
>> >
>> > declare @sql nvarchar(4000)
>> >
>> > set @sql = N'
>> > select *
>> > from customers
>> > where companyname = @par1'
>> >
>> > print @sql
>> > exec sp_executesql @sql, N'@par1 nvarchar(40)', @par1
>> > go
>> >
>> > create table t(colA int)
>> > go
>> >
>> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> > go
>> >
>> > select * from t
>> > go
>> >
>> > drop table t
>> > go
>> >
>> >
>> > AMB
>> >
>> > "Infoliber" wrote:
>> >
>> >> Hola,
>> >> mirando el help me parecio que para que no me pudieran inyectar
>> >> codigo
>> >> desde un campo de consulta era mejor poner storedprocedures.
>> >>
>> >> He empezado una aplicacion en asp.net y todas las consultas las
>> >> hago
>> >> con
>> >> storedProcedures pero no veo el motivo por el cual se evita la
>> >> inyeccion
>> >> de
>> >> codigo, si yo le paso a un parametro una parte de codigo este se
>> >> pasa
>> >> al
>> >> sql
>> >> server, lo veo igual que hacer la consulta sin los
>> >> storedProcedures.
>> >>
>> >> ¿Como se puede evitar la inyeccion de codigo?
>> >>
>> >> Gracias
>> >>
>> >>
>> >>
>>
>>
>>



Respuesta Responder a este mensaje
#8 Alejandro Mesa
18/03/2005 - 17:07 | Informe spam
Maxi,

Estoy de acuerdo contigo, pero el ejemplo de Miguel crea la sentencia en la
aplicacion cliente. Si en este caso, por ejemplo, creamos el procedimiento:

create procedure dbo.usp_check_user
@login varchar(10),
@password varchar(10),
@ok int output
as
set nocount on

declare @user nvarchar(256)
declare @app nvarchar(128)
declare @workstation nvarchar(128)

if not exists(select * from usuarios where login = @login)
begin
raiserror('No existe login [%s].', 16, 1, @login)
return 0
end

if exists(select * from usuarios where login = @login and password =
@password)
set @ok = 1
else
begin
set @ok = 0
set @user = suser_sname()
set @app = app_name()
set @workstation = cast(host_name() as nvarchar(128))

raiserror('Incorrect password. login=[@login]; user=[%s]; app=[%s];
workstation=[%s].', 16, 1, @login, @user, @app, @workstation) with log
end

return 0
go

y lo llamamos desde la aplicacion cliente, entonces no veo como pudieramos
inyectar codigo.


AMB

"Maxi" wrote:

Si ya se, pero no me entendiste creo. Proba de armar un Sp's y usar las ' y
veras las maravillas que puedes hacer :)

Lo que te queria decir que no alcanza solo con usar SP, sino que tambien hay
que controlar como vienen los datos.


Salu2
Maxi


"Alejandro Mesa" escribió en el
mensaje news:
> Maxi,
>
> Esto es cuando generas la sentencia dinamicamente en la aplicacion
> cliente.
> Esto es peor, no solo debes chequear la inyeccion de codigo, sino que si
> debes arreglar algo o cambiarlo, debes buscar por cuanta aplicacion
> tengas.
>
>
> AMB
>
>
> "Maxi" wrote:
>
>> Hola mi amigo, te paso un articulo de Miguel Egea donde muestra algunas
>> cosas de las que te comente ;)
>>
>> http://www.configuracionesintegrale...p?articulo4
>>
>> prometo buscarte algo mas especifico en cuento a los parametros de los
>> sp's
>> :-)
>>
>>
>> Salu2
>> Maxi
>>
>>
>> "Alejandro Mesa" escribió en el
>> mensaje news:
>> > Hombre, donde has estado?
>> >
>> >> Ojo ALe, hay veces que un SP puede tener un param varcghar(300) y ya
>> >> ahi
>> >> puedes injectar mucho codigo aunque no lo creas, y no es necesario
>> >> usar
>> >> sql-dinamico para que esto suceda
>> >
>> > No se me ocurre como, pudieras exponernos un ejemplo?
>> >
>> >
>> > AMB
>> >
>> >
>> >
>> >
>> > "Maxi" wrote:
>> >
>> >> Ojo ALe, hay veces que un SP puede tener un param varcghar(300) y ya
>> >> ahi
>> >> puedes injectar mucho codigo aunque no lo creas, y no es necesario
>> >> usar
>> >> sql-dinamico para que esto suceda
>> >>
>> >>
>> >> Salu2
>> >> Maxi
>> >>
>> >>
>> >> "Alejandro Mesa" escribió en
>> >> el
>> >> mensaje news:
>> >> > Una forma de evitar inyeccion atraves de los sp es el tipo de dato
>> >> > de
>> >> > los
>> >> > parametros. Si declaras @par1 como INT entonces que vas a inyectar?.
>> >> > Tambien
>> >> > si el parametro es por ejemplo char(3), pues no podras inyectar
>> >> > mucho
>> >> > que
>> >> > digamos. El problema estaria en aquellos sp que usan sql dinamico y
>> >> > esperan
>> >> > parametros con tipo de datos char / nchar/ varchar / etc., y para
>> >> > poder
>> >> > inyectar codigo habria que de alguna manera cerrar la cadena.
>> >> >
>> >> > Ejemplo:
>> >> >
>> >> > use northwind
>> >> > go
>> >> >
>> >> > alter procedure proc1
>> >> > @par1 nvarchar(40)
>> >> > as
>> >> > set nocount on
>> >> >
>> >> > declare @sql nvarchar(4000)
>> >> >
>> >> > set @sql = N'
>> >> > select *
>> >> > from customers
>> >> > where companyname = ''' + @par1 + ''''
>> >> >
>> >> > print @sql
>> >> > exec sp_executesql @sql
>> >> > go
>> >> >
>> >> > create table t(colA int)
>> >> > go
>> >> >
>> >> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> >> > go
>> >> >
>> >> > select * from t
>> >> > go
>> >> >
>> >> > Fijate en la sentencia que se armo dinamicamente.
>> >> >
>> >> > Puedes hacer lo siguiente, si vas a usar sql dinamico. Usar
>> >> > sp_executesql
>> >> > y
>> >> > no EXEC(), usar parametros en el procedimiento sp_executesql o
>> >> > duplicar
>> >> > todos
>> >> > los apostrofes dentro del parametro pasado.
>> >> >
>> >> > alter procedure proc1
>> >> > @par1 nvarchar(40)
>> >> > as
>> >> > set nocount on
>> >> >
>> >> > declare @sql nvarchar(4000)
>> >> >
>> >> > set @sql = N'
>> >> > select *
>> >> > from customers
>> >> > where companyname = ''' + replace(@par1, '''', '''''') + ''''
>> >> >
>> >> > print @sql
>> >> > exec sp_executesql @sql
>> >> > go
>> >> >
>> >> > create table t(colA int)
>> >> > go
>> >> >
>> >> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> >> > go
>> >> >
>> >> > select * from t
>> >> > go
>> >> >
>> >> > drop table t
>> >> > go
>> >> >
>> >> > alter procedure proc1
>> >> > @par1 nvarchar(40)
>> >> > as
>> >> > set nocount on
>> >> >
>> >> > declare @sql nvarchar(4000)
>> >> >
>> >> > set @sql = N'
>> >> > select *
>> >> > from customers
>> >> > where companyname = @par1'
>> >> >
>> >> > print @sql
>> >> > exec sp_executesql @sql, N'@par1 nvarchar(40)', @par1
>> >> > go
>> >> >
>> >> > create table t(colA int)
>> >> > go
>> >> >
>> >> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> >> > go
>> >> >
>> >> > select * from t
>> >> > go
>> >> >
>> >> > drop table t
>> >> > go
>> >> >
>> >> >
>> >> > AMB
>> >> >
>> >> > "Infoliber" wrote:
>> >> >
>> >> >> Hola,
>> >> >> mirando el help me parecio que para que no me pudieran inyectar
>> >> >> codigo
>> >> >> desde un campo de consulta era mejor poner storedprocedures.
>> >> >>
>> >> >> He empezado una aplicacion en asp.net y todas las consultas las
>> >> >> hago
>> >> >> con
>> >> >> storedProcedures pero no veo el motivo por el cual se evita la
>> >> >> inyeccion
>> >> >> de
>> >> >> codigo, si yo le paso a un parametro una parte de codigo este se
>> >> >> pasa
>> >> >> al
>> >> >> sql
>> >> >> server, lo veo igual que hacer la consulta sin los
>> >> >> storedProcedures.
>> >> >>
>> >> >> ¿Como se puede evitar la inyeccion de codigo?
>> >> >>
>> >> >> Gracias
>> >> >>
>> >> >>
>> >> >>
>> >>
>> >>
>> >>
>>
>>
>>



Respuesta Responder a este mensaje
#9 Miguel Egea
18/03/2005 - 22:13 | Informe spam
Ese código que tu montas no tiene posiblidad de inyección de código SQL es
correcto.

La inyección de código tiene dos vertientes, muchos desarrolladores pasan
parámetros a sus aplicaciones(por ejemplo asp) en la url imagina algo así

http://tuempresa.com/mostrarcuenta?idCliente#,

Bien, tanto si se arma la sentencia en asp como en SQL en un stored, si la
sentencia se arma con ejecución dinámica puedes tener ese problema

Imagina asp
SQL="select * from cliente where idcliente=" + Request("idcliente"),

Si algún listillo te teclea algo así (fijaos que el %20 es el espacio)
http://tuempresa.com/mostrarcuenta?...ving%201=1 ,
tu sentencia queda algo así
Select * from clientes where idcliente# having 1=1
Lo más normal es que aparezca un error diciendo que uno de los nombres de tu
tabla no está en group by (acaba de averiguar como se llama tu primer campo)
Column 'Clientes.dni' is invalid in the select list because it is not
contained in an aggregate function and there is no GROUP BY clause.

Si te teclean algo así
http://tuempresa.com/mostrarcuenta?...%20by%2024 ,
tu sentencia queda algo así
Select * from clientes where idcliente# order by 24
Lo más normal es que el error sea algo así
The ORDER BY position number 24 is out of range of the number of items in
the select list.

Iterando puede obtener el número de columnas que tienes y después
simplemente puede añadirte detrás un union all con un select por ejemplo de
sysobjects, tu aplicación lo más normal es que muy amablemente le muestre
los nombres de tus tablas, y a partir de ahí, pues ya imagina lo que puede
hacer

Como vés esto no se soluciona sustituyendo un ' por dos ', ya que aquí solo
hay caracteres numéricos, el problema no son los strings o los números sino
la forma de construir las sentencias.

Esto se solucionaría así
SQL="select * from cliente where idcliente=@idCliente"
y después si por ejemplo es .net
Comando.Parameters.add y añadiendo así el valor de la variable.

Si esto lo hacemos con procedures también tenemos el mismo problema imagina
que el código es

SQL="Exec DameCliente " + Request("idcliente"),

y Dame cliente es algo así, muy sencillo

create table clientes(idcliente int primary key,nombre nvarchar(100))
go
create procedure DameClientes @idcliente int
as
select * from clientes where idcliente=@idcliente
go
Si en la url te teclean algo así
http://tuempresa.com/mostrarcuenta?...e%clientes ,
tu sentencia SQl queda algo así
exec Dameclientes 23 drop table clientes

Si lanzas mi script y lo pruebas verás que tu tabla clientes desaparecerá
sin dejar rastro

Espero que este correo ayude a entender el problema y a evitar que lo
hagamos.

Saludos



"Alejandro Mesa" escribió en el
mensaje news:
Maxi,

Estoy de acuerdo contigo, pero el ejemplo de Miguel crea la sentencia en
la
aplicacion cliente. Si en este caso, por ejemplo, creamos el
procedimiento:

create procedure dbo.usp_check_user
@login varchar(10),
@password varchar(10),
@ok int output
as
set nocount on

declare @user nvarchar(256)
declare @app nvarchar(128)
declare @workstation nvarchar(128)

if not exists(select * from usuarios where login = @login)
begin
raiserror('No existe login [%s].', 16, 1, @login)
return 0
end

if exists(select * from usuarios where login = @login and password > @password)
set @ok = 1
else
begin
set @ok = 0
set @user = suser_sname()
set @app = app_name()
set @workstation = cast(host_name() as nvarchar(128))

raiserror('Incorrect password. login=[@login]; user=[%s]; app=[%s];
workstation=[%s].', 16, 1, @login, @user, @app, @workstation) with log
end

return 0
go

y lo llamamos desde la aplicacion cliente, entonces no veo como pudieramos
inyectar codigo.


AMB

"Maxi" wrote:

Si ya se, pero no me entendiste creo. Proba de armar un Sp's y usar las '
y
veras las maravillas que puedes hacer :)

Lo que te queria decir que no alcanza solo con usar SP, sino que tambien
hay
que controlar como vienen los datos.


Salu2
Maxi


"Alejandro Mesa" escribió en el
mensaje news:
> Maxi,
>
> Esto es cuando generas la sentencia dinamicamente en la aplicacion
> cliente.
> Esto es peor, no solo debes chequear la inyeccion de codigo, sino que
> si
> debes arreglar algo o cambiarlo, debes buscar por cuanta aplicacion
> tengas.
>
>
> AMB
>
>
> "Maxi" wrote:
>
>> Hola mi amigo, te paso un articulo de Miguel Egea donde muestra
>> algunas
>> cosas de las que te comente ;)
>>
>> http://www.configuracionesintegrale...p?articulo4
>>
>> prometo buscarte algo mas especifico en cuento a los parametros de los
>> sp's
>> :-)
>>
>>
>> Salu2
>> Maxi
>>
>>
>> "Alejandro Mesa" escribió en
>> el
>> mensaje news:
>> > Hombre, donde has estado?
>> >
>> >> Ojo ALe, hay veces que un SP puede tener un param varcghar(300) y
>> >> ya
>> >> ahi
>> >> puedes injectar mucho codigo aunque no lo creas, y no es necesario
>> >> usar
>> >> sql-dinamico para que esto suceda
>> >
>> > No se me ocurre como, pudieras exponernos un ejemplo?
>> >
>> >
>> > AMB
>> >
>> >
>> >
>> >
>> > "Maxi" wrote:
>> >
>> >> Ojo ALe, hay veces que un SP puede tener un param varcghar(300) y
>> >> ya
>> >> ahi
>> >> puedes injectar mucho codigo aunque no lo creas, y no es necesario
>> >> usar
>> >> sql-dinamico para que esto suceda
>> >>
>> >>
>> >> Salu2
>> >> Maxi
>> >>
>> >>
>> >> "Alejandro Mesa" escribió
>> >> en
>> >> el
>> >> mensaje news:
>> >> > Una forma de evitar inyeccion atraves de los sp es el tipo de
>> >> > dato
>> >> > de
>> >> > los
>> >> > parametros. Si declaras @par1 como INT entonces que vas a
>> >> > inyectar?.
>> >> > Tambien
>> >> > si el parametro es por ejemplo char(3), pues no podras inyectar
>> >> > mucho
>> >> > que
>> >> > digamos. El problema estaria en aquellos sp que usan sql dinamico
>> >> > y
>> >> > esperan
>> >> > parametros con tipo de datos char / nchar/ varchar / etc., y para
>> >> > poder
>> >> > inyectar codigo habria que de alguna manera cerrar la cadena.
>> >> >
>> >> > Ejemplo:
>> >> >
>> >> > use northwind
>> >> > go
>> >> >
>> >> > alter procedure proc1
>> >> > @par1 nvarchar(40)
>> >> > as
>> >> > set nocount on
>> >> >
>> >> > declare @sql nvarchar(4000)
>> >> >
>> >> > set @sql = N'
>> >> > select *
>> >> > from customers
>> >> > where companyname = ''' + @par1 + ''''
>> >> >
>> >> > print @sql
>> >> > exec sp_executesql @sql
>> >> > go
>> >> >
>> >> > create table t(colA int)
>> >> > go
>> >> >
>> >> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> >> > go
>> >> >
>> >> > select * from t
>> >> > go
>> >> >
>> >> > Fijate en la sentencia que se armo dinamicamente.
>> >> >
>> >> > Puedes hacer lo siguiente, si vas a usar sql dinamico. Usar
>> >> > sp_executesql
>> >> > y
>> >> > no EXEC(), usar parametros en el procedimiento sp_executesql o
>> >> > duplicar
>> >> > todos
>> >> > los apostrofes dentro del parametro pasado.
>> >> >
>> >> > alter procedure proc1
>> >> > @par1 nvarchar(40)
>> >> > as
>> >> > set nocount on
>> >> >
>> >> > declare @sql nvarchar(4000)
>> >> >
>> >> > set @sql = N'
>> >> > select *
>> >> > from customers
>> >> > where companyname = ''' + replace(@par1, '''', '''''') + ''''
>> >> >
>> >> > print @sql
>> >> > exec sp_executesql @sql
>> >> > go
>> >> >
>> >> > create table t(colA int)
>> >> > go
>> >> >
>> >> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> >> > go
>> >> >
>> >> > select * from t
>> >> > go
>> >> >
>> >> > drop table t
>> >> > go
>> >> >
>> >> > alter procedure proc1
>> >> > @par1 nvarchar(40)
>> >> > as
>> >> > set nocount on
>> >> >
>> >> > declare @sql nvarchar(4000)
>> >> >
>> >> > set @sql = N'
>> >> > select *
>> >> > from customers
>> >> > where companyname = @par1'
>> >> >
>> >> > print @sql
>> >> > exec sp_executesql @sql, N'@par1 nvarchar(40)', @par1
>> >> > go
>> >> >
>> >> > create table t(colA int)
>> >> > go
>> >> >
>> >> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> >> > go
>> >> >
>> >> > select * from t
>> >> > go
>> >> >
>> >> > drop table t
>> >> > go
>> >> >
>> >> >
>> >> > AMB
>> >> >
>> >> > "Infoliber" wrote:
>> >> >
>> >> >> Hola,
>> >> >> mirando el help me parecio que para que no me pudieran
>> >> >> inyectar
>> >> >> codigo
>> >> >> desde un campo de consulta era mejor poner storedprocedures.
>> >> >>
>> >> >> He empezado una aplicacion en asp.net y todas las consultas las
>> >> >> hago
>> >> >> con
>> >> >> storedProcedures pero no veo el motivo por el cual se evita la
>> >> >> inyeccion
>> >> >> de
>> >> >> codigo, si yo le paso a un parametro una parte de codigo este se
>> >> >> pasa
>> >> >> al
>> >> >> sql
>> >> >> server, lo veo igual que hacer la consulta sin los
>> >> >> storedProcedures.
>> >> >>
>> >> >> ¿Como se puede evitar la inyeccion de codigo?
>> >> >>
>> >> >> Gracias
>> >> >>
>> >> >>
>> >> >>
>> >>
>> >>
>> >>
>>
>>
>>






Respuesta Responder a este mensaje
#10 MAXI
18/03/2005 - 23:40 | Informe spam
Aparecio el master de los master :-), me ganaste de mano con la respuesta
:( pero la verdad que la hiciste mucho mejor de lo que la pensaba responder
yo y ademas aprendi cosas :-)

Muchas gracias maestro, deberias estar mas seguido por aqui, se te extraña
:S



Maxi
Buenos Aires - Argentina
Desarrollador .NET 3 Estrellas
Microsoft User Group (MUG)



"Miguel Egea" escribió en el mensaje
news:%238%234Q9$
Ese código que tu montas no tiene posiblidad de inyección de código SQL es
correcto.

La inyección de código tiene dos vertientes, muchos desarrolladores pasan
parámetros a sus aplicaciones(por ejemplo asp) en la url imagina algo así

http://tuempresa.com/mostrarcuenta?idCliente#,

Bien, tanto si se arma la sentencia en asp como en SQL en un stored, si
la sentencia se arma con ejecución dinámica puedes tener ese problema

Imagina asp
SQL="select * from cliente where idcliente=" + Request("idcliente"),

Si algún listillo te teclea algo así (fijaos que el %20 es el espacio)
http://tuempresa.com/mostrarcuenta?...ving%201=1 ,
tu sentencia queda algo así
Select * from clientes where idcliente# having 1=1
Lo más normal es que aparezca un error diciendo que uno de los nombres de
tu tabla no está en group by (acaba de averiguar como se llama tu primer
campo)
Column 'Clientes.dni' is invalid in the select list because it is not
contained in an aggregate function and there is no GROUP BY clause.

Si te teclean algo así
http://tuempresa.com/mostrarcuenta?...%20by%2024 ,
tu sentencia queda algo así
Select * from clientes where idcliente# order by 24
Lo más normal es que el error sea algo así
The ORDER BY position number 24 is out of range of the number of items in
the select list.

Iterando puede obtener el número de columnas que tienes y después
simplemente puede añadirte detrás un union all con un select por ejemplo
de sysobjects, tu aplicación lo más normal es que muy amablemente le
muestre los nombres de tus tablas, y a partir de ahí, pues ya imagina lo
que puede hacer

Como vés esto no se soluciona sustituyendo un ' por dos ', ya que aquí
solo hay caracteres numéricos, el problema no son los strings o los
números sino la forma de construir las sentencias.

Esto se solucionaría así
SQL="select * from cliente where idcliente=@idCliente"
y después si por ejemplo es .net
Comando.Parameters.add y añadiendo así el valor de la variable.

Si esto lo hacemos con procedures también tenemos el mismo problema
imagina que el código es

SQL="Exec DameCliente " + Request("idcliente"),

y Dame cliente es algo así, muy sencillo

create table clientes(idcliente int primary key,nombre nvarchar(100))
go
create procedure DameClientes @idcliente int
as
select * from clientes where idcliente=@idcliente
go
Si en la url te teclean algo así
http://tuempresa.com/mostrarcuenta?...e%clientes ,
tu sentencia SQl queda algo así
exec Dameclientes 23 drop table clientes

Si lanzas mi script y lo pruebas verás que tu tabla clientes desaparecerá
sin dejar rastro

Espero que este correo ayude a entender el problema y a evitar que lo
hagamos.

Saludos



"Alejandro Mesa" escribió en el
mensaje news:
Maxi,

Estoy de acuerdo contigo, pero el ejemplo de Miguel crea la sentencia en
la
aplicacion cliente. Si en este caso, por ejemplo, creamos el
procedimiento:

create procedure dbo.usp_check_user
@login varchar(10),
@password varchar(10),
@ok int output
as
set nocount on

declare @user nvarchar(256)
declare @app nvarchar(128)
declare @workstation nvarchar(128)

if not exists(select * from usuarios where login = @login)
begin
raiserror('No existe login [%s].', 16, 1, @login)
return 0
end

if exists(select * from usuarios where login = @login and password >> @password)
set @ok = 1
else
begin
set @ok = 0
set @user = suser_sname()
set @app = app_name()
set @workstation = cast(host_name() as nvarchar(128))

raiserror('Incorrect password. login=[@login]; user=[%s]; app=[%s];
workstation=[%s].', 16, 1, @login, @user, @app, @workstation) with log
end

return 0
go

y lo llamamos desde la aplicacion cliente, entonces no veo como
pudieramos
inyectar codigo.


AMB

"Maxi" wrote:

Si ya se, pero no me entendiste creo. Proba de armar un Sp's y usar las
' y
veras las maravillas que puedes hacer :)

Lo que te queria decir que no alcanza solo con usar SP, sino que tambien
hay
que controlar como vienen los datos.


Salu2
Maxi


"Alejandro Mesa" escribió en
el
mensaje news:
> Maxi,
>
> Esto es cuando generas la sentencia dinamicamente en la aplicacion
> cliente.
> Esto es peor, no solo debes chequear la inyeccion de codigo, sino que
> si
> debes arreglar algo o cambiarlo, debes buscar por cuanta aplicacion
> tengas.
>
>
> AMB
>
>
> "Maxi" wrote:
>
>> Hola mi amigo, te paso un articulo de Miguel Egea donde muestra
>> algunas
>> cosas de las que te comente ;)
>>
>> http://www.configuracionesintegrale...p?articulo4
>>
>> prometo buscarte algo mas especifico en cuento a los parametros de
>> los
>> sp's
>> :-)
>>
>>
>> Salu2
>> Maxi
>>
>>
>> "Alejandro Mesa" escribió
>> en el
>> mensaje news:
>> > Hombre, donde has estado?
>> >
>> >> Ojo ALe, hay veces que un SP puede tener un param varcghar(300) y
>> >> ya
>> >> ahi
>> >> puedes injectar mucho codigo aunque no lo creas, y no es necesario
>> >> usar
>> >> sql-dinamico para que esto suceda
>> >
>> > No se me ocurre como, pudieras exponernos un ejemplo?
>> >
>> >
>> > AMB
>> >
>> >
>> >
>> >
>> > "Maxi" wrote:
>> >
>> >> Ojo ALe, hay veces que un SP puede tener un param varcghar(300) y
>> >> ya
>> >> ahi
>> >> puedes injectar mucho codigo aunque no lo creas, y no es necesario
>> >> usar
>> >> sql-dinamico para que esto suceda
>> >>
>> >>
>> >> Salu2
>> >> Maxi
>> >>
>> >>
>> >> "Alejandro Mesa"
>> >> escribió en
>> >> el
>> >> mensaje news:
>> >> > Una forma de evitar inyeccion atraves de los sp es el tipo de
>> >> > dato
>> >> > de
>> >> > los
>> >> > parametros. Si declaras @par1 como INT entonces que vas a
>> >> > inyectar?.
>> >> > Tambien
>> >> > si el parametro es por ejemplo char(3), pues no podras inyectar
>> >> > mucho
>> >> > que
>> >> > digamos. El problema estaria en aquellos sp que usan sql
>> >> > dinamico y
>> >> > esperan
>> >> > parametros con tipo de datos char / nchar/ varchar / etc., y
>> >> > para
>> >> > poder
>> >> > inyectar codigo habria que de alguna manera cerrar la cadena.
>> >> >
>> >> > Ejemplo:
>> >> >
>> >> > use northwind
>> >> > go
>> >> >
>> >> > alter procedure proc1
>> >> > @par1 nvarchar(40)
>> >> > as
>> >> > set nocount on
>> >> >
>> >> > declare @sql nvarchar(4000)
>> >> >
>> >> > set @sql = N'
>> >> > select *
>> >> > from customers
>> >> > where companyname = ''' + @par1 + ''''
>> >> >
>> >> > print @sql
>> >> > exec sp_executesql @sql
>> >> > go
>> >> >
>> >> > create table t(colA int)
>> >> > go
>> >> >
>> >> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> >> > go
>> >> >
>> >> > select * from t
>> >> > go
>> >> >
>> >> > Fijate en la sentencia que se armo dinamicamente.
>> >> >
>> >> > Puedes hacer lo siguiente, si vas a usar sql dinamico. Usar
>> >> > sp_executesql
>> >> > y
>> >> > no EXEC(), usar parametros en el procedimiento sp_executesql o
>> >> > duplicar
>> >> > todos
>> >> > los apostrofes dentro del parametro pasado.
>> >> >
>> >> > alter procedure proc1
>> >> > @par1 nvarchar(40)
>> >> > as
>> >> > set nocount on
>> >> >
>> >> > declare @sql nvarchar(4000)
>> >> >
>> >> > set @sql = N'
>> >> > select *
>> >> > from customers
>> >> > where companyname = ''' + replace(@par1, '''', '''''') + ''''
>> >> >
>> >> > print @sql
>> >> > exec sp_executesql @sql
>> >> > go
>> >> >
>> >> > create table t(colA int)
>> >> > go
>> >> >
>> >> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> >> > go
>> >> >
>> >> > select * from t
>> >> > go
>> >> >
>> >> > drop table t
>> >> > go
>> >> >
>> >> > alter procedure proc1
>> >> > @par1 nvarchar(40)
>> >> > as
>> >> > set nocount on
>> >> >
>> >> > declare @sql nvarchar(4000)
>> >> >
>> >> > set @sql = N'
>> >> > select *
>> >> > from customers
>> >> > where companyname = @par1'
>> >> >
>> >> > print @sql
>> >> > exec sp_executesql @sql, N'@par1 nvarchar(40)', @par1
>> >> > go
>> >> >
>> >> > create table t(colA int)
>> >> > go
>> >> >
>> >> > exec proc1 N'''; drop table t; select 1 where '''' = '''
>> >> > go
>> >> >
>> >> > select * from t
>> >> > go
>> >> >
>> >> > drop table t
>> >> > go
>> >> >
>> >> >
>> >> > AMB
>> >> >
>> >> > "Infoliber" wrote:
>> >> >
>> >> >> Hola,
>> >> >> mirando el help me parecio que para que no me pudieran
>> >> >> inyectar
>> >> >> codigo
>> >> >> desde un campo de consulta era mejor poner storedprocedures.
>> >> >>
>> >> >> He empezado una aplicacion en asp.net y todas las consultas las
>> >> >> hago
>> >> >> con
>> >> >> storedProcedures pero no veo el motivo por el cual se evita la
>> >> >> inyeccion
>> >> >> de
>> >> >> codigo, si yo le paso a un parametro una parte de codigo este
>> >> >> se
>> >> >> pasa
>> >> >> al
>> >> >> sql
>> >> >> server, lo veo igual que hacer la consulta sin los
>> >> >> storedProcedures.
>> >> >>
>> >> >> ¿Como se puede evitar la inyeccion de codigo?
>> >> >>
>> >> >> Gracias
>> >> >>
>> >> >>
>> >> >>
>> >>
>> >>
>> >>
>>
>>
>>











Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida