{ WillyXoft .NET }

Blog de Willy Mejía sobre Microsoft .NET Framework y temas relacionados...

<July 2008>
SuMoTuWeThFrSa
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789


Navigation

e-Grupos / Foros

Web/Blog Amigos

INETA & MUGs

Subscriptions

News

Post Categories

Article Categories



Seguridad

Artículos sobre temas de seguridad: autenticación, código seguro, etc.

El Modelado de Amenazas

Traducción del artículo "Threat Model Your Security Risks".
Realizada por Willy Mejía [WillyXoft].

En el mundo de componentes distribuidos débilmente acoplados del .NET, el compartir datos sensibles a través de las redes a significado un aumento de la exposición a los atacantes hambrientos por sus datos. Usted necesita crear un modelo de seguridad firme para beneficiarse de la visión de .NET de una informática totalmente funcional y distribuida. El fracaso para lograr esto puede llevar al desastre. Entonces ¿Cómo se asegura que su aplicación es tan segura como necesita ser? Bien, debe empezar con el Modelado de Amenazas (Threat Model), un acercamiento iterativo para evaluar las vulnerabilidades en su aplicación para encontrar aquéllas que son las más peligrosas porque exponen los datos más sensibles. A partir de allí, se crea un conjunto priorizado de contramedidas para manejar el riesgo.

El mejor lugar para aprender acerca del Modelado de Amenazas y su rol en la arquitectura global y el proceso de diseño es el documento titulado "Improving Web Application Security: Threats and Countermeasures" ("Mejorando la Seguridad de las Aplicaciones Web: Amenazas y Contramedidas"), ubicado en el sitio Web de Microsoft patterns & practices.

Hay un acercamiento del seis pasos para crear un Modelo de Amenazas:

  1. Identificar los activos
  2. Crear una descripción de la arquitectura
  3. Descomponer la aplicación
  4. Identificar las amenazas
  5. Documentar las amenazas
  6. Asignar prioridades a las amenazas

El primero paso es obvio: Identificar sus activos —la valiosa información que maneja o los recursos a los que accede su aplicación. Cada sitio maneja algunos datos confidenciales, desde sueldos hasta los números del Seguro Social. Usted no sabrá qué quieren los hackers hasta que haya identificado la información sensible en su sitio.

El siguiente paso es desarrollar una descripción global de la arquitectura. Usted necesita ser explícito sobre el propósito de la aplicación (Casos de Uso), sobre cómo planea llevar a cabo la arquitectura y el diseño de la aplicación para lograr esa funcionalidad, y sobre qué tecnologías se exigen para implementar el diseño. Esto le ayudará a identificar las amenazas comunes específicas a la tecnología y a implementar las soluciones para superarlas.

Los Casos de Uso y el modelo arquitectónico le ayudarán a descomponer su aplicación, que es el tercer paso. Cuanto más sepa sobre su aplicación, más fácil es descubrir las amenazas. Este paso involucra la descomposición de su aplicación para crear un "perfil de seguridad". Aceptando el axioma que todo dato (de entrada) es maligno, usted debe realizar la validación contra todos los datos enviados por los subsistemas. Un examen exhaustivo de los "límites de confianza", los flujos de datos, y los puntos de entrada asegurarán que todos los handoffs son realizados de una manera segura.

En el cuarto paso, usted identifica las amenazas que pudieran afectar a su sistema y comprometer a sus activos. Para tomar un acercamiento metódico, se debe trabajar por encima de la pila: Desde las amenazas a la red, a través de las amenazas al host, y finalmente las amenazas a la aplicación. Para evaluar las amenazas a la red, investigue cómo los datos pasan a través del router, firewalls, y switches. Ésta es la estrategia de "defensa a profundidad" a nivel de la red en la que necesita determinar que se requiere para pasar mas allá de cada gatekeeper. Cuando investigue el host, examine las categorías de configuración comunes aplicables a todos los recursos del servidor (parches, archivos, directorios, y así sucesivamente). Finalmente, concéntrese en la aplicación. La mejor manera de ir a lo profundo con su aplicación es usar "árboles de ataque" los cuales definan un ataque potencial en su sistema de una manera estructural y jerárquica. "Improving Web Application Security" entra en mayores detalles sobre cómo crear y usar los "árboles de ataque".

En el quinto paso, se documentará cada amenaza —la descripción de la amenaza, el blanco de ataque, el riesgo de llevarse a cabo el ataque, las técnicas que probablemente serán empleadas para perpetrar el ataque, y una estrategia para el manejo del riesgo. Por ejemplo, al tratar con un ataque "SQL Injection", el blanco es su base de datos y la técnica es teclear un comando en un cuadro de texto el cual se agrega automáticamente dentro de un comando T-SQL sin la validación del lado cliente. Para oponerse a ésta amenaza, utilice expresiones regulares para validar el nombre del usuario, y use una consulta parameterizada para acceder a la base de datos.

Hasta ahora ha estado en el modo de recolección de datos, determinando cada posible agujero en su aplicación. El paso seis es asignarles prioridad. Manejar cada una de las amenazas concebibles no es práctico, pero necesita hacer una valoración de riesgo para asignarle prioridad y tratar a las más importantes. Esto requiere un poco de matemática simple: la probabilidad de ocurrencia multiplicada por el daño potencial al ocurrir. La buena noticia es que ésta es una manera simple de asignar prioridad; la mala noticia es que ésta es una manera muy simple de asignar prioridad. Esto es algo subjetivo para dar un acercamiento meticuloso a la identificación de los riesgos. Hay acercamientos más completos para la valoración de riesgos.

Microsoft utiliza al modelo DREAD ("pavor" en inglés) para evaluar el riesgo con una granularidad mayor que la matemática simple descrita anteriormente. El DREAD son las siglas en inglés que definen cinco atributos importantes para medir cada vulnerabilidad: Damage potential (potencial de daño), Reproducibility (grado de reproducción), Exploitability (grado de explotación), Affected users (usuarios afectado), y Discoverability (grado de descubrimiento). "Improving Web Application Security" detalla cómo Microsoft emplea el DREAD para asignar prioridades a los riesgos y mitigarlos.

Estos seis pasos completan el proceso. Ahora está listo para implementar apropiadamente su estrategia de seguridad. El Modelado de Amenazas es un acercamiento indispensable para evitar los desastres que podrían constituir noticias de primera plana.

posted Monday, July 10, 2006 6:00 PM by vbpuntonet with 0 Comments

Envio de correo electronico por SMTP con autenticacion Rated Excellent [5 out of 5].

Por Willy Mejía [WillyXoft]

Este artículo muestra como podemos enviar correo electrónico por medio de servidores SMTP que requieren credenciales de autenticación.

Envío de correo electrónico en .NET

Para que una aplicación .NET pueda realizar envío de correo electrónico con el .NET Framework 1.x se emplea el espacio de nombres System.Web.Mail, que contiene las clases que permiten construir y enviar mensajes mediante el componente COM de mensajería conocido como CDO (Collaboration Data Objects) formalmente llamado "Microsoft CDO for Windows 2000 Library" que se incluye en Windows 2000 y posteriores. El mensaje de correo se entrega por medio del servicio de correo SMTP (Simple Mail Transport Protocol) ya sea con el servidor incluido con IIS o bien mediante algún otro servidor SMTP externo. Las clases de System.Web.Mail se pueden utilizar desde cualquier aplicación administrada ya sea Web (ASP.NET) o Windows.

Imports System.Web.Mail
Module Module1
  Sub Main()
    Dim oMsg As MailMessage = New MailMessage()
    oMsg.From = "sender@somewhere.com"
    oMsg.To = "recipient@somewhere.com"
    oMsg.Subject = "Send using Web Mail"
    oMsg.BodyFormat = MailFormat.Html
    oMsg.Body = "Hello World!"
    SmtpMail.SmtpServer = "smtp.domain.com"
    SmtpMail.Send(oMsg)
  End Sub
End Module

Lo anterior lo podemos emplear también en el .NET Framework 2.0, no obstante éste introduce una serie clases mejoradas para la comunicación por red, incluyendo aquellas relacionadas con el envío de correo electrónico. Dichas clases se encuentran bajo el Namespace System.Net.Mail y ya no son un wrapper para CDO.

Imports System.Net.Mail
Module Module1
  Sub Main()
    Dim oMsg As MailMessage = New MailMessage()
    oMsg.From = "sender@somewhere.com"
    oMsg.To = "recipient@somewhere.com"
    oMsg.Subject = "Send using Web Mail"
    oMsg.IsBodyHtml = True
    oMsg.Body = "Hello World!"
    Dim oClient As SmtpClient = New SmtpClient("smtp.domain.com")
    oClient.Send(oMsg)
  End Sub
End Module

En este caso MailMessage es una nueva clase que pertenece al Namespace System.Net.Mail, por lo que no es la misma clase del Namespace System.Web.Mail aun presente por compatibilidad. Se observa también que ahora se tiene que crear una instancia de la nueva clase SmtpClient para realizar el envío de correo electrónico.

El Problema: El servicio SMTP requiere autenticación

Con el fin de evitar el envío de correo electrónico con remitente falso y reducir el spam, algunos servidores de correo electrónico SMTP requieren que el usuario se autentifique antes de enviar un mensaje. Si bajo estas circunstancias se envía un correo electrónico sin las credenciales de autenticación se recibe un mensaje error.

Note Nota

¿Cómo determinar si el error es a causa de falta de autenticación?

Cuando el método SmtpMail.Send de System.Web.Mail no puede completar el envío del mensaje de correo electrónico, se dispara una excepción con un mensaje parecido a:

No se puede obtener acceso al objeto 'CDO.Message'.

Lamentablemente dicho mensaje no brinda mayor información sobre la causa real del problema. Por ello debemos utilizar InnerException para conocer la excepción interna que dió origen a la excepción actual. Como en el ejemplo siguiente, donde EscribeLog es una función para escribir el Log en un archivo, una base de datos, o al EventLog:

    Try
        System.Web.Mail.SmtpMail.Send(Correo)
    Catch ex As System.Exception
        EscribeLog("Excepción: " & ex.Message)
        Do Until (ex.InnerException Is Nothing)
            EscribeLog("Excepción interna: " & _
                ex.InnerException.ToString())
            ex = ex.InnerException
        Loop
    End Try

De este modo podemos determinar la causa por la qué no se pudo enviar el mensaje. Si la causa tiene que ver con la falta de autenticación entonces continue leyendo.

Para resolver el problema del envío de correo electrónico mediante un servidor SMTP que requiere credenciales autenticación tenemos tres soluciones:

Estableciendo las Credenciales de Autenticación en CDO.

La configuración del componente CDO se establece a través de un conjunto de propiedades en forma de pares de nombre/valor llamados CDO Fields. Dichos Campos se implementan en una Colección de tipo ADODB.Fields llamada a su vez Fields. Esta implementación esta asociada al objeto Configuration de CDO quien a su vez esta asociado a los distintos objetos de CDO. Es entonces que debemos emplear el objeto Configuration para definir parámetros de configuración específicos al objeto Message de CDO a través de su colección Fields para así establecer los valores de los Campos necesarios para establecer las credenciales de autenticación.

Todos los campos que necesitamos establecer se encuentran bajo el Espacio de Nombres de CDO (no confundir con los Namespaces de .NET) "http://schemas.microsoft.com/cdo/configuration/" que se encuentran agrupadas en la Biblioteca de CDO bajo el Módulo CdoConfiguration, y que están representados por constantes que equivalen al nombre completo del Campo, esto es: Espacio de nombres + Nombre del campo. Así por ejemplo, la constante cdoSMTPAuthenticate equivale al Campo smtpauthenticate cuyo nombre completo es: "http://schemas.microsoft.com/cdo/configuration/smtpauthenticate".

Mediante el campo smtpauthenticate podemos indicar el mecanismo de autenticación requerida para enviar los mensajes, los valores permitidos se listan en el Enumerado CdoProtocolsAuthentication, que alberga a tres constantes: cdoAnonymous (valor numérico 0), cdoBasic (valor numérico 1) y cdoNTLM (valor numérico 2).

Para que el campo smtpauthenticate sea tomado en cuenta debe establecerse a su vez el campo sendusing ("http://schemas.microsoft.com/cdo/configuration/sendusing"), al valor de la constante cdoSendUsingPort (valor numérico 2) del Enumerado CdoSendUsing, este campo define si se debe enviar el mensaje utilizando el servicio local SMTP (si es que el host local tuviese el servicio SMTP instalado) o un servicio SMTP externo sobre la red de trabajo local, que es el que debemos establecer.

También debe establecerse el valor del campo smtpserver ("http://schemas.microsoft.com/cdo/configuration/smtpserver") con la dirección IP específica o el nombre DNS del host que alberga el servicio SMTP, y en caso de ser necesario, debe establecerse el valor numérico del puerto del mismo en el campo smtpserverport ("http://schemas.microsoft.com/cdo/configuration/smtpserverport").

Por último y mas importante, para establecer las credenciales de autenticación requeridas para la conexión con el servicio SMTP, deben establecerse los valores de los campos sendusername ("http://schemas.microsoft.com/cdo/configuration/sendusername") y sendpassword ("http://schemas.microsoft.com/cdo/configuration/sendpassword") correspondientes a el nombre de usuario (login) y la contraseña de usuario. Estos dos campos junto con el campo smtpauthenticate son los indispensables para establecer las credenciales de autenticación para el servidor SMTP.

En resumen, los Campos CDO a emplear y cuyos valores debemos establecer son:

  • smtpserver: Nombre del servidor SMTP.
  • smtpserverport: Puerto del servidor SMTP (25).
  • sendusing: Método de envío, establecido a cdoSendUsingPort (2) para el uso de la red de trabajo.
  • smtpauthenticate: Mecanismo de autenticación hacia el servicio SMTP sobre la red de trabajo. Establecido a cdoBasic (1).
  • sendusername: Nombre de usuario
  • sendpassword: Contraseña

Utilizando CDO (cdosys.dll) para el envío de mensajes con autenticación.

Este primer método no emplea el Namespace System.Web.Mail, sino que emplea directamente la Biblioteca de tipos de CDO a través de Interoperabilidad COM. Para ello lo primero que tenemos que hacer es crear nuestro Ensamblado de Interoperabilidad. Desde su IDE puede hacerlo agregando la referencia COM de dicho componente, o bien, desde la línea de comandos lo obtenemos escribiendo:

>tlbimp cdosys.dll /out:Interop.CDO.dll

Podemos ahora elaborar un ejemplo con VB.NET, para ello creamos un Proyecto de Consola y agregamos la referencia de CDO, o bien, simplemente creamos un archivo de nombre Module1.vb con "Visual Notepad". Después, introducimos el código siguiente:

Option Explicit On 
Module Module1
Sub Main()
Const ConfigNamespace As String = _
"http://schemas.microsoft.com/cdo/configuration/"
Dim oMsg As New CDO.Message()
Dim iConfig As New CDO.Configuration()
Dim Flds As ADODB.Fields = iConfig.Fields
With Flds
.Item(ConfigNamespace & "smtpserver").Value = "smtp.mail.dominio"
.Item(ConfigNamespace & "smtpserverport").Value = 25
.Item(ConfigNamespace & "sendusing").Value = _ CDO.CdoSendUsing.cdoSendUsingPort
.Item(ConfigNamespace & "sendusername").Value = "usuario"
.Item(ConfigNamespace & "sendpassword").Value = "contraseña"
.Item(ConfigNamespace & "smtpauthenticate").Value = _ CDO.CdoProtocolsAuthentication.cdoBasic
.Update()
End With
With oMsg
.Configuration = iConfig
.From = "usuario@dominio"
.To = "alguien@dominio"
.Subject = "Test con CDO"
.TextBody = "Hola Mundo"
.Send()
End With
oMsg = Nothing
iConfig = Nothing
End Sub
End Module

Nota: Debe cambiar los valores de los campos y propiedades por aquellos que correspondan a su caso particular.

Compilamos desde nuestro IDE, o bien, para compilar desde la línea de comandos:

>vbc Module1.vb /r:Interop.CDO.dll,adodb.dll

Nota: El ensamblado ADODB.DLL es el PIA (Primary Interop Assembly) de ADO (ActiveX Data Objects) que por lo general se encuentra en: %programfiles%\Microsoft.NET\Primary Interop Assemblies\ En caso contrario deberá crearse manualmente con tlbimp.

Esta es la única solución para el envío de correo electrónico con autenticación para la versión 1.0 del .NET Framework, mas puede funcionar también con las versiones 1.1 y 2.0.

Utilizando MailMessage.Fields para el envío de mensajes con autenticación.

En la documentación del .Net Framework versión 1.1 se observa que la clase System.Web.Mail.MailMessage tiene un nuevo miembro llamado Fields —mismo que hasta el día de hoy no esta del todo documentado— con el cual podemos establecer los valores de la colección Fields de la biblioteca CDO.

Para probarlo modificaremos el código anterior cambiando los objetos CDO por sus equivalentes en System.Web.Mail, empleando un System.Collections.IDictionary en lugar de ADODB.Fields, así como cambiando las nombres de las constantes CDO por sus valores numéricos correspondientes para evitar cualquier referencia a CDO, teniendo como resultado el siguiente código:

Option Explicit On 
Module Module1
Sub Main()
Const ConfigNamespace As String = _
"http://schemas.microsoft.com/cdo/configuration/"
Dim oMsg As New System.Web.Mail.MailMessage
Dim Flds As System.Collections.IDictionary
Flds = oMsg.Fields
With Flds
.Add(ConfigNamespace & "smtpserver", "smtp.mail.dominio")
.Add(ConfigNamespace & "smtpserverport", 25)
.Add(ConfigNamespace & "sendusing", 2)
.Add(ConfigNamespace & "sendusername", "usuario")
.Add(ConfigNamespace & "sendpassword", "contraseña")
.Add(ConfigNamespace & "smtpauthenticate", 1)
End With
With oMsg
.From = "usuario@dominio"
.To = "alguien@dominio"
.Subject = "Test con MailMessage.Fields"
.Body = "Hola Mundo"
End With
System.Web.Mail.SmtpMail.Send(oMsg)
End Sub
End Module

Nota: Debe cambiar los valores de los campos y propiedades por aquellos que correspondan a su caso particular.

Observe que dado a que el código se especificó el Host del servicio SMTP mediante el campo "smtpserver" ya no es necesario hacerlo mediante la propiedad SmtpServer. Por otro lado, si se emplea la propiedad SmtpServer se pueden omitir los campos "smtpserver", "smtpserverport" y "sendusing" y sólo necesitaríamos especificar los tres campos restantes: "sendusername", "sendpassword" y "smtpauthenticate".

De este modo podemos enviar mensajes con autenticación sin necesidad de emplear la Biblioteca COM de CDO mediante Interoperabilidad COM gracias a la propiedad Fields de MailMessage presente a partir de la versión 1.1 del .Net Framework. Por ende esta solución no funciona en la versión 1.0 pero sí en la versión 2.0 del .NET Framework.

Utilizando SmtpClient para el envío de mensajes con autenticación.

Dado que las nuevas clases bajo el Namespace System.Net.Mail del .NET Framework 2.0 ya no emplean CDO, las credenciales de autenticación ya no se especifican mediante Campos CDO de ningún tipo. En lugar de ello se utilizan o especifican las Credenciales de Red a través de la instancia de la clase SmtpClient creada para el envío de correo electrónico.

Si se desea autenticar con las credenciales del usuario actual debemos especificarlo utilizando la propiedad UseDefaultCredentials de SmtpClient y establecer su valor a True. Tal y como se muestra en la siguiente sentencia:

mySmtpClient.UseDefaultCredentials = True

Para especificar credenciales distintas deberá utilizarse la propiedad Credentials de SmtpClient que es de tipo ICredentialsByHost. Por lo que podemos asignar una instancia de la clase System.Net.NetworkCredential que albergará las credenciales a utilizar. Por ejemplo, para establecer las cadenas de usuario y contraseña (empleando Autenticación Básica) podemos utilizar la siguiente sentencia:

mySmtpClient.Credentials = _
New System.Net.NetworkCredential("usuario", "contraseña")

Ahora modifiquemos el ejemplo visto en los casos anteriores para utilizar las nuevas clases del .NET Framework 2.0.

Option Explicit On
Module Module1
  Sub Main()
    Dim oMsg As New System.Net.Mail.MailMessage
    With oMsg
      .From = "usuario@dominio"
      .To = "alguien@dominio"
      .Subject = "Test con SmtpClient"
      .Body = "Hola Mundo"
    End With
    Dim oClient As New System.Net.Mail.SmtpClient("smtp.mail.dominio")
    oClient.UseDefaultCredentials = False
    oClient.Credentials = _
    New System.Net.NetworkCredential("usuario", "contraseña")
    oClient.Send(oMsg)
  End Sub 
End Module

Nota: Debe cambiar los valores de los constructores y propiedades por aquellos que correspondan a su caso particular.

Tal y como se aprecia, el código necesario se ha simplificado y reducido considerablemente. Se puede reducir aun mas si se establece la configuración del envío de correo electrónico mediante los archivos de configuración, tal y como se muestra a continuación.

<configuration>
  <system.net>
    <mailsettings>
      <smtp deliverymethod="network">
        <network host="smtp.mail.dominio" port="25" defaultcredentials="false" username="usuario" password="contraseña">
        </network>
      </smtp>
    </mailsettings>
  </system.net>
</configuration>

De manera que el código queda reducido a:

Option Explicit On
Module Module1
  Sub Main()
    Dim oMsg As New System.Net.Mail.MailMessage
    With oMsg
      .From = "usuario@dominio"
      .To = "alguien@dominio"
      .Subject = "Test con SmtpClient"
      .Body = "Hola Mundo"
    End With
    Dim oClient As New System.Net.Mail.SmtpClient()
    oClient.Send(oMsg)
  End Sub 
End Module

Utilizar el archivo de configuración permite que el código sea reutilizable y la configuración fácil de personalizar si las condiciones han cambiado. Por ejemplo, si en lugar de un servidor SMTP externo ahora se desea utilizar el servicio SMTP de IIS, sólo tendremos que cambiar la configuración como se muestra a continuación:

<configuration>
  <system.net>
    <mailsettings>
      <smtp deliverymethod="PickupDirectoryFromIis">
      </smtp>
    </mailsettings>
  </system.net>
</configuration>

Aunque también es posible establecer el método de envío (deliveryMethod) y otros parámetros mediante código, tal y como lo hemos visto, es mejor establecerlo de ésta manera.

Note Nota de seguridad

La utilización de Autenticación Básica implica enviar los valores de userName y password al servidor sin encriptar. Cualquier persona que este monitoreando el tráfico de la red puede ver las credenciales y utilizarlas para conectarse al servidor. Por ello se recomienda utilizar mecanismos de autenticación más seguros, tales como Kerberos o NTLM. Dichos protocolos se utilizan si se emplea defaultCredentials con el valor establecido a true (aplicable con el .NET Framework 2.0), siempre y cuando el servidor los soporte.

Resumen

En el presente artículo se han presentado tres formas, una para cada versión del .NET Framework, para el envío de correo electrónico mediante servidores SMTP que requieren autenticación. Las dos primeras consisten en manipular los Campos de Configuración de CDO: "smtpserver", "smtpserverport" y "sendusing" para establecer los valores necesarios, siendo la única diferencia que la primero utiliza CDO mediante Interoperabilidad COM, y la segundo emplea la propiedad Fields de System.Web.Mail.MailMessage presente a partir del .NET Framework 1.1. La última consiste en utilizar las propiedades de las nuevas clases del .NET Framework 2.0 agrupadas bajo el Namespace System.Net.Mail, así como utilizando los archivos de configuración.

posted Thursday, February 02, 2006 2:05 PM by vbpuntonet with 1 Comments

Protegerse de un ataque SQL Injection Rated Good [4 out of 5].

Por Willy Mejía [WillyXoft]

Este artículo muestra que és un ataque "SQL Injection" y cómo evitar que nuestras aplicaciones sean vulnerables al mismo.

Introducción.

"SQL Injection" es el nombre en inglés del ataque contra un Gestor de Bases de Datos Relacional que aprovecha la vulnerabilidad de una aplicación cliente del mismo. Dicha vulnerabilidad consiste en permitir mandar instrucciones SQL adicionales a partir de un campo o un parámetro de entrada - por lo que se dice han sido "inyectadas". La finalidad del ataque es realizar tareas sobre la base de datos y de ser posible sobre host mismo, teniendo resultados indeseables e inesperados que van desde la alteración de un dato hasta apoderarse del servidor.

El ataque "SQL Injection" es posible dadas ciertas características del dialecto -o lenguaje- SQL que lo dotan de flexibilidad, tales como:

  • Poder embeber comentarios en una sentencia SQL
  • Poder escribir varias sentencias SQL juntas y ejecutarlas en bloque.
  • Poder realizar consultas de metadatos por medio de "tablas de sistema".

Por este motivo cualquier RDBM que entiende SQL llámese Oracle, DB2, SQL Server, MySQL, etc. es susceptible de recibir un ataque de este tipo a través de sus aplicaciones cliente - este ataque se produce a nivel de aplicación- ya sean de tipo Consola, Windows o Web e independiente de la plataforma de desarrollo (Java, Win32, .NET, etc.) con la que fue elaborada.

Escenario vulnerable.

Veamos un caso hipotético de una aplicación de acceso a datos que emplea entradas de usuario como parámetros de una consulta SQL común. Es típico que este tipo de consultas sean construidas dinámicamente utilizando sentencias SQL con concatenación de variables, al estilo:

"SELECT campo1, campo2,..., campoN FROM tablaX 
WHERE campo1=" + mValor [+ ...]

Donde mValor esta dado por una entrada de usuario. Son éstas entradas las puertas a un SQL Injection ya que, dependiendo del tipo de dato de mValor, si en lugar de la entrada esperada se coloca:

a) ' Or 1=1 -- 
b) 0 Or 1=1 --
c) #01/01/01# Or 1=1 -- 

Se puede realizar una consulta no deseada, ya que siguiendo el primer caso, el resultado es la sentencia siguiente:

"SELECT campo1, campo2,..., campoN FROM tablaX
WHERE campo1='' Or 1=1 -- lo que siga no importa" 

Lo que se consigue es de hacer válida la consulta al añadir una cláusula OR que siempre será cierta (1=1) así como de obligar al intérprete SQL a omitir el resto de la sentencia SQL original al introducir el guión doble (--) que le indica que lo subsiguiente es un comentario. Con ello el atacante puede, por ejemplo, tener acceso a la aplicación sin necesidad de contar con las credenciales adecuadas.

Por otro lado se podrían realizar consultas de los metadatos, es decir de las tablas del sistema del gestor, para conocer los nombres de las tablas de usuario y sus respectivos campos. Para ello podemos utilizar la cláusula UNION y hacer coincidir el número y los tipos de los campos de la consulta original de la aplicación para hacer algo como:

' UNION SELECT id, name,'', 0,'' FROM sysobjects 
WHERE xtype='U' --
' UNION SELECT 0, name, '', 0,'' FROM sy