Cita:
Iniciado por Myakire Para que no digas que nadie sigue el código
:
<input type="password" id="pwd" name="pwd" maxlength="8"
vcalue="" />
Mis padres no pudieron venir, pero mi padre se aventó una firma sobre el citatorio
espero que con eso ya pueda volver a entrar a tan interesante clase
Gracias
con respecto a "la firma de tu padre", esteeeeeeeeee, mejor ni hablar :-p
Bueno chic@s, nos quedamos en que necesitabamos implementar nuestro primer método público de la clase usuario que nos servirá para autentificar a nuestro usuario.
Primero que nada, dos recomendaciones importantes con respecto al acceso a datos:
1. No dejen campos nulos en sus tablas si no es algo que realmente se necesite, los datos nulos ralentizan las consultas y le dan a la aplicación una tarea extra que hacer -manejar otro tipo de dato-, en la medida de lo posible, utiliza valores por defecto para tus campos, estandarízalos de modo que tu aplicación los entienda, por ejemplo, yo se que en mis aplicaciones la fecha '1/1/1800' es regularmente un valor por defecto salvo en los casos que estemos tratando de fechas históricas, así pues, vamos a poner valores por defecto a nuestros campos:
usuario_uname | ''
usuario_pwd | ''
2. Parametricen sus consultas, es una buena práctica que ayuda a tener un orden, saber precisamente el tipo de dato, su longitud, por si fuera poco, ayuda a controlar la inyección de SQL,
esta es una lectura que siempre recomiendo, creo recordar que existia el mismo artículo en español, pero no encontré el link
Nuestra forma tradicional de hacer consultas SQL, es un string, al cual concatenamos variables, dicho en nuestro idioma:
Código:
Ej. 1
uname = Request("valor")
pwd = Request("valor")
query = "SELECT usuario_id FROM tbl_usuario WHERE usuario_uname = '" & uname & "' AND pwd = '" & pwd & "'"
Está perfecto ¿no es así? el query se forma correctamente y la sintáxis es correcta, ahora qué pasa si envío los siguientes valores?
usuario
' OR 1 = 1
pwd
' OR 'A' = 'A
Sutituimos los valores:
Código:
SELECT usuario_id FROM tbl_usuario WHERE usuario_uname = '' OR 1 = 1 AND pwd = '' OR 'A' = 'A'
A mi me parece una sentencia correcta y que además siempre será verdadera ¿A tí?
La solución es controlar la comilla simple, pero ¿Qué pasa en el caso de valores numéricos? Supóngase el caso de una página de detalles donde envíamos el id por querystring:
Código:
SELECT campos FROM tabla WHERE campoid = Request.QueryString("id")
Recuerden que para hacer un ataque, se require un poco de intuición, así que supongamos que mediante ciertas excepciones provocadas, nuestro atacante se entera de que tenemos un campo llamado user_uname y nos envía por querystring lo siguiente:
id=1+update tbl_usuario set usuario_uname='<script type=text/javascript>location.href=http://www.unsitio.com</script>'
NUestra consulta quedaría de la siguiente forma:
Código:
SELECT campos FROM tabla WHERE campoid = 1+update tbl_usuario set usuario_uname='<script type=text/javascript>location.href=http://www.unsitio.com</script>'
Woops, que crees? también es una consulta válida, que no solo nos hace una inyección de sql, sino también nos inyectan javascript.
Recuerda que ninguna técnica debe tomarse como religión, quizás te puedas valer de ciertas funciones para reemplazar los posibles ataques de este tipo, pero en todo este tiempo que he estado trabajando con ASP, no he encontrado nada más ordenado, simple y concreto que el objeto command como medio de seguridad.
*El objeto Command desmistificado:
Te voy a poner la parte condensada sin tantos rodeos, básicamente se trata de hacer nuestra consulta, y en lugar de concatenar variables de VBS, envíamos a la consulta un caractér que nuestro objeto reconoce como un parámetro, y se representa mediante un signo de interrogación (?), cada parámetro necesita tener un:
nombre, tipo de dato, tipo de parámetro, tamaño y valor
¿Qué datos requiere el objeto command?
- Conexión activa
- Tipo de Comando
- Texto del comando, la consulta
- Parámetros
-Tipos de datos más comunes para parámetros y su tamaño
adInteger | 4
adDouble | 8
adDate | 8
adVarChar | tamaño del campo
adBoolean | 1
adLongVarChar | regularmente mas de 1000,000
Aterrizando todo:
Código:
Dim ObjConn
Dim rs
Dim cmd
Dim param
Dim qry
Dim id
id = Request.QueryString("id")
'Comando
Set cmd = Server.CreateObject("ADODB.Command")
Set rs = Server.CreateObject("ADODB.Recordset")
Set ObjConn = Server.CreateObject("ADODB.Connection")
'CommandText
qry = "SELECT campo FROM tabla WHERE campoid = ?"
'Parámetro en orden, solo tenemos uno, el id
Set param = cmd.CreateParameter("id", adInteger, adParamInput, 4, id)
cmd.Parameters.Append(param)
ObjConn.Open strConnect
'Conexion activa
cmd.ActiveConnection = ObjConn
'Tipo de comando
cmd.CommandType = adCmdText
'command text para el comando
cmd.CommandText = qry
'abrimos nuestro recordset
rs.Open cmd
Y eso sería todo...qué crees? que me extendí mucho y no me da más tiempo de implementar el método, así que lo dejaremos para el rato
Saludos