martes, 28 de noviembre de 2006

Seguridad en SQL: Truncamiento (MSDN)

En el número de Noviembre de la excelente revista MSDN Magazine, hay un artículo dedicado a la prevención de un nuevo tipo de ataques de intrusión a Bases de Datos, la inyección de SQL por truncamiento. Es curioso que, cuando parecía que ya teníamos superados estos inconvenientes, resulta que aparecen otros nuevos. Y además, provocados por actualizaciones que se le efectúan al software.

Un ejemplo de esto, es éste párrafo del artículo: "una función REPLACE en cada variable de 25 caracteres puede devolver 50 caracteres cuando todos los caracteres son comillas simples. SP4 de SQL Server 2000 y SP1 de SQL Server 2005 truncan de forma silenciosa los datos si la variable no tiene búferes lo suficientemente grandes. Esto proporciona a los posibles atacantes la posibilidad de truncar la cadena de comando."

Supongo que estarán de acuerdo conmigo en que no es precisamente tranquilizador. De todas formas, lo más importante es que se nos muestra cómo identificar, y también cómo evitar, estos ataques. Además está traducido al cristiano. ;)

Enlace al artículo, aquí.

martes, 21 de noviembre de 2006

Boxing y Unboxing

Pues como ya hacía tiempo que no posteaba nada 'útil' en el blog, vamos a arrancarnos por peteneras con un didáctico articulillo sobre esta característica de .NET.

El Boxing no es otra cosa que convertir un tipo "valor" (Int, Double, Structs...) en un tipo "referencia". La utilidad de esto, se puede encontrar si en alguna ocasión necesitamos pasarle un parámetro, que por definición sería "por valor", a un método que requiere parámetros que son tipos por Referencia (esto puede ocurrir con más frecuencia de lo que pensamos, y entonces nos vemos obligados a sobrecargar nuestras funciones, o a crear nuevas -OJO no confundir con el modificador ref de C#, ByRef de VB.NET).

¿Cómo se hace el Box? Muy sencillo, tenemos la siguiente variable:


int i = 35; // Esas rimas fáciles...

Y queremos utilizarla en un método, que podría ser por ejemplo éste:

static void ManejaUnObjeto(object o)
{
...
}

Primer problema: el método recibe un objeto (un tipo por Referencia), y nosotros queremos pasarle un entero (tipo por valor)... Evidentemente no podemos incluir un ref en la llamada al método puesto que no está declarado para aceptarlo. ¿Solución? Nada mejor que "convertir" esa variable, precisamente en un objeto (la Madre De Todos los tipos por Referencia). Así conseguimos pasarle la variable al método:

object objEntero = i;
ManejaUnObjeto(objEntero);

Segundo problema: Ya tengo la variable (o algo parecido) dentro del método. ¿Cómo demonios la utilizo?

static void ManejaUnObjeto(object Objeto)
{
int j = int(Objeto);
}

Para poder utilizar el valor correctamente, debemos hacer el "Unboxing" del parámetro, que no es otra cosa que un Cast al tipo de dato correspondiente. Pero ojo, porque el tipo DEBE ser el mismo de la variable original:

static void ManejaUnObjeto(object Objeto)
{
double j = double(Objeto); // Esto pega un petardazo.
}

Tenemos dos soluciones para ésto: O bien interceptamos la excepción con un try...catch(InvalidCastException) o bien nos aseguramos de que el tipo sea el esperado (es más elegante esta opción, por supuesto):

static void ManejaUnObjeto(object Objeto)
{
if(Objeto is int)
{ int j = int(Objeto); }
}

Otro aspecto a tener en cuenta es cuando le pasamos a ese método un tipo definido por nosotros:

// Definimos esta estructura (recordar que es tipo por VALOR,
// al contrario que la Clase)

struct Estructura
{
public int i, j;
}

// Definimos dentro del Main una variable de ese tipo y la
// pasamos a un método

static void Main(string[] args)
{
Estructura struc;
struc.i = 10;
struc.j = 20;
MetodoEstructura(struc);
}

Vemos aquí que no hemos hecho el Box, es decir, no hemos convertido la estructura en objeto. Esto es perfectamente válido y no es mucho problema, en principio. Por regla general, .NET hace el Boxing automáticamente cuando se encuentra que pasamos un tipo por Valor a un método que espera un objeto ("vaya, ¿entonces para qué lo explicas?" Pues porque nunca está de más saber las cosas :P ).

Proseguimos con el código anterior. Vamos ahora a escribir el método que recibe y utiliza esta estructura:

static void MetodoEstructura(object Objeto)
{
Console.WriteLine("Valor 0 {0}, Valor 1 {1}", Objeto.i,
Objeto.j);
}

Este método ni siquiera compila. ¿Motivo? Que la clase System.Object no tiene ningún miembro llamado 'i' o 'j', y aunque el compilador es capaz de hacer el Box automático del parámetro de entrada, NO hace la acción inversa. Hemos pues de proceder al Unbox manual:

static void MetodoEstructura(object Objeto)
{
// Ahora si...
if(Objeto is Estructura)
{
Estructura s = (Estructura)Objeto;
Console.WriteLine("Valor 0 {0}, Valor 1 {1}", s.i, s.j);
}
else
Console.WriteLine("No has enviado una Estructura!");
}

Una cuestión a tener en cuenta es que las operaciones de Box y Unbox, como cualquier Cast, consumen algo de tiempo de proceso y si se utilizan con demasiada frecuencia, el rendimiento de nuestra Aplicación podría verse afectado (podría). Sin embargo desde la versión 2.0 de la plataforma hay una posible solución a esto, y es el uso de los "nuevos" tipos genéricos (parecido al Variant de toda la vida de los que conocemos Delphi, jeje :P ... Sólo que en principio el uso del tipo Variant en Delphi SI penaliza el rendimiento, y los genéricos en .NET, al parecer, no lo hacen).

miércoles, 15 de noviembre de 2006

CodeGear?? Sí hombre, los del Delphi...

Acabo de leer en el Blog de Rafael Ontivero, que al final en Borland se han tomado al pie de la letra aquello de: "Ni lo uno ni lo otro, sino todo lo contrario". Que de lo de vender la División de Herramientas de Desarrollo, nada de nada (no encontraron un "comprador adecuado", dicen). Pero que tampoco se la quedan, y crean esa "nueva empresa", con ese "nuevo nombre" (y la web es... escueta, por decir algo).

O sea, que había que hacerlo como fuese, pero si de paso se llevaban unos milloncejos pues mejor que mejor. Con lo cual uno de mis temores desde hace tiempo, se confirma: A Borland le "sobraba" su división de Desarrollo. Borland prescinde de quien hizo de Borland lo que hoy es: Los desarrolladores. Borland ha visto una posible gallina de los huevos de oro en dirigir sus productos a gente que por lo general no tiene ni peregrina idea de software (Directivos, etc). Vale, yo entiendo que es más factible cobrar muchísimos miles de dólares por un producto diseñado para que un stakeholder piense que controla la información, o crea que sabe diseñar una aplicación de Software (ah, bendito UML...), que "sólo" unos pocos miles por una herramienta de desarrollo que lleva ya varios años caduca, obsoleta y que la han superado por todas partes... y que encima tus clientes lo saben, porque saben de qué va el tema.

Una cosa que no termino de entender, es ese empecinamiento en mantener la marca Borland para herramientas que no tienen nada que ver con el mundo del desarrollo, cuando PRECISAMENTE toda la vida de Borland como empresa ha sido para y por los desarrolladores. Desde hace más de 15 años, decir "Borland" equivalía a decir "Herramientas de Desarrollo". O mejor dicho: "Las MEJORES Herramientas de Desarrollo". Tirar ésto por la borda, y ningunear a los MILLONES de fieles desarrolladores que con orgullo nos definíamos como "Borlanders", tildándolos como bien dice Rafael de "mierdecillas, ínfimos seres privilegiados capaces de usar sus fantásticas herramientas", a mí me parece el mayor error de esta empresa. Y ha cometido unos cuantos, y gordos, en estos últimos años (¿Alguien recuerda aquello de Inprise?).

Pues, y ésta es sólo mi humilde opinión, podrían haberse quedado con el nombre Inprise para nombrar a la división de Herramientas de gestión de Proyectos (ALM); que ya les venía MUY bien para el lema que tenía Inprise (Integrating the enterprise), y "cederle" el nombre Borland a lo que SIEMPRE había sido Borland. Habría sido sencillamente perfecto.

Pero no, tenían que hacerlo de esta manera, que sólo se me ocurre calificar de... triste.

martes, 14 de noviembre de 2006

The .NETrix ya es la Nº 11 en Google!!

Hoy me he llevado una gran alegría: Resulta que se me ha ocurrido buscar en Google "Netrix", así tal cual... y cuál no sería mi sorpresa que este blog sale en el número 11 de la lista de resultados. O dicho de otra manera (que suena aún mejor :P), el Primero de la segunda página. El total de resultados que devuelve Google para la palabra "Netrix" es de más de 480.000 y hace no mucho (tres o cuatro meses) no figuraba ni en los 500 primeros... así que, creo que tengo muchas razones para estar tan contento :)

Y si encima busco sólo los resultados en español... ¡¡el cuarto lugar absoluto!! uff! Lo dejo ya, que me estoy poniendo burro xDD

Saludos y GRACIAS a los lectores y visitantes de esta humilde página. :)

lunes, 13 de noviembre de 2006

Internet Explorer 7, descarga ya en castellano

Bueno, pues algunos días después de la liberación oficial de la versión final de IE7 en inglés, nos llega hoy la oportunidad por fin de descargárnoslo en español.

Por cierto no quisiera hacer leña del árbol caído, pero es que a veces no sé si lo hacen aposta o qué. Me refiero a la frase que puede leerse en la home de Microsoft Ibérica al respecto de esta noticia: "Actualice sin miedo".

De verdad, yo creo que a alguien dentro del Departamento de Márketing, o Comunicación o lo que corresponda, de ésta empresa, deberían cuando menos "recomendarle" que escoja mejor las palabras...

En fin. Ah otra cosita, recordad que sólo se pueden actualizar los usuarios de Windows XP SP2 y Windows Server 2003 SP1.

martes, 7 de noviembre de 2006

Liberada oficialmente la versión 3.0 de .NET Framework

Hoy 7 de noviembre ha sido oficialmente liberada la versión 3.0 (anteriormente conocida como WinFX) de la plataforma .NET, y se puede descargar, en inglés de momento, desde este enlace (el Runtime) y este otro (el SDK).

Podéis también visitar la página principal de la Plataforma, hay más enlaces, por ejemplo a las extensiones para VS2005 de WWF (Windows Workflow Foundation), información sobre las nuevas tecnologías como CardSpace, y otros.