InicioArticulos y noticiasBases de datosProgramaciónForosInternetServiciosContratacionEmail
También puedes ver ...
SQL Server 2008
Google Trends, adiós Alexa adiós ...
Fiddler - Indispensable para el desarrollo Web
LinQ To SQL - Un ejemplo sencillo
Formatear números en SQL Server
Cómo activar Intelisense (autocompletado) en el Web.config
Leer un campo XML de SQL Server 2005 con C#
TripleDES - Un ejemplo practico en C#
Mostrar un GridView dentro de un DataList
Sitios Web de ejemplo ASP.NET

Afiliados
La Web del programador
MundoProgramacion


 

Seguridad en Internet.

SQL Injections.

    SQL Injections es una técnica por la cúal un atacante de una página Web es capaz de acceder a nuestra base de datos y ejecutar sentencias SQL sobre ella.

    La técnica se basa en aprovechar las páginas con formularios de toma de datos (logins, busquedas ...) para montar sentencias SQL que se ejecutaran en el servidor aprovechando los errores comunes de programación en los entornos Web.

    El escenario sobre el que vamos a desarrollar el articulo es una página de login que dará acceso a la zona privada de la Web. Esta página solicitará el nombre de usuario y password de acceso. El código de la página está escrito en ASP, pero debemos tener claro que SQL Injections no es una vulnerabilidad de ASP, sino que cualquier página PHP, JSP, ASP.NET, CGI ... es susceptible de recibir este tipo de ataques.

    El siguiente código html ilustra la página de entrada de datos, la página se guardará con el nombre frmLogin.html:

 
<html>
 <body>
  <form name="frmLogin" action="/asp/login.asp" method="post">
   <table align="center" border="1" >
    <tr>
     <td align="center" colspan="2"><b> Datos de Acceso </b>
     </td>
    </tr>
    <tr>
     <td>Usuario:</td>
     <td><input type="text" name="usrtxt" ID="Text1" /></td>
    </tr>
    <tr>
     <td>Password:</td>
     <td><input type="text" name="pwdtxt" ID="Text2" /></td>
    </tr>
   </table>
   <p align="center"><input type="submit" value="enviar" ></p>
  </form>
 </body>
</html>

    En este ejemplo hemos dejado el campo password (pwdtxt) como texto normal, para poder ver que es lo que tecleamos.

      Los datos se envian a la pagina login.asp, que recoge los parámetros de la página frmLogin.html, y consulta nuestra base de datos para comprobar si el nombre de usuario y password es correcto. La base de datos podría tener los datos que muestra la imagen.

 
     El codigo de login.asp sería así:

   
<% 
      Option Explicit
      Dim strLogin, strPassword, strSQL 
      Dim connection, rs 
      strLogin = Request("usrtxt")  
      strPassword = Request("pwdtxt") 
      strSQL = " SELECT * FROM USUARIOS " & _          
         " WHERE USUARIO='" & strLogin & "' AND " &_
         "       PASSWORD='" & strPassword & "'"
      Set connection = Server.CreateObject("ADODB.Connection")
connection.Open "DRIVER={SQL Server};SERVER=SERVIDOR;" _
& "Database=DBNAME;User Id=USER;password=CLAVE" 

      Set rs = connection.Execute(strSQL) 
     
      If( Not rs.EOF ) Then           
            Response.Write("Indentificacion correcta")             
      else 
            Response.Write("Indentificacion INCORRECTA") 
      End If 
     
      rs.Close 
      connection.Close

      Set rs = Nothing 
      Set connection = Nothing
   %>

   
    Esta sería una página totalmente normal que cualquier desarrollador medio podría haber desarrollado. Existen miles de páginas como ésta (y peores) colgadas en Internet, en ocasiones como única "guardia" de datos valiosos.

    El funcionamiento de la página es simple, se conecta a la base de datos, ejecuta la consulta contra la base de datos y nos valida o invalida el acceso. Sencillo.

    Supongamos que el usuario llega a su formulario de identificación, e inserta los datos "Devjoker" como identificación y "secreta" como contraseña. Por tanto, la cadena SQL que ejecutaría la página sería como esta:

 


SELECT * FROM USUARIOS
WHERE USUARIO='Devjoker' AND password='secreta'

    Este es el funcionamiento esperado, pero un atacante podría introducir ciertos valores que alteren este comportamiento ....        

    Para entender el ataque hay que tener dos conceptos previos:

  • SQL no utiliza comillas dobles para los valores de texto, sino comillas simples.
  • Los comentarios en lenguaje SQL se escriben con un doble guíon "--".

    Con estas premisas resulta sencillo "cerrar" la cláusula SQL que creemos que el servidor va a ejecutar mediante los valores que introducimos en la página frmLogin.html.

    En la casilla Login, se escribiría un valor cualquiera, por ejemplo "usuario", y en la casilla Password, escribiríamos lo siguiente : 'or 1=1 --. 

    El formulario de entrada de datos quedaría del siguiente modo:
              Usuario:USUARIO_CUALQUIERA
              Clave:'  OR 1=1 --

    El resultado es que el sistema nos da acceso ...

    ¿Que ha pasado?¿Porque ha dado como válido el usuario y la contraseña si en realidad no lo son?

    Cuando la página login.asp forma su sentencia SQL, concatena los valores que hemos enviado desde frmLogin.html. La primera comilla simple que hemos tecleado en el campo password hace que se cierre la cadena, y se añade una cláusula OR que siempre será cierta (1=1). Además, para prevenir que el sistema dé un error, ya que todavía quedaría una comilla simple sin cerrar, se añade el símbolo del comentario en SQL, que hace que el sistema no haga caso al resto de la cadena SQL.      
   
    La sentencia SQL que finalmente ejecutaría el servidor es:


SELECT *
  FROM USUARIOS
 WHERE USUARIO = 'usuario'
   AND PASSWORD ='' OR 1=1 --'

    Como resultado de la ejecución de esta consulta tendremos acceso a la zona privada. En realidad da lo mismo lo que pongamos en el campo usuario, ya que la segunda condición se cumple siempre y se especifica con un operador OR. 
  
    El uso de nombres de usuario previsibles, tales como "Admin" o "Administrador" es otra puerta abierta. Si tecleamos "Admin" como usuario, la query quedaría del siguiente modo ...


SELECT *
  FROM USUARIOS
 WHERE USUARIO = 'ADMIN'
   AND PASSWORD ='' OR 1=1 --'

    Si se produce este caso, no solo tenemos acceso al sistema sino que además tendremos privilegios de administrador.

    Pero la peor parte de este tipo de ataques esta por llegar. Algunos gestores de bases de datos son capaces de ejecutar mas de una sentencia SQL, separadas por punto y coma. Por lo que si sabemos cual es el nombre de una tabla podríamos ejecutar sentencias SQL con la intención de borrar los datos o la propia tabla.

    En el siguiente ataque el usuario introduce los siguientes valores:
              Usuario:Pedro
              Clave:' HAVING 1=1 --

    La sentencia SQL que se compone es la siguiente:


SELECT
*
  FROM USUARIOS
 WHERE USUARIO = 'ADMIN'
   AND PASSWORD ='' HAVING 1=1 --

    La sentencia SQL que ha quedado formada es incorrecta, por lo que la ejecución fallará y se devolverá el error correspondiente, en nuestro caso seria el siguiente:

Microsoft OLE DB Provider for ODBC Drivers (0x80040E14)
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'USUARIOS.CO_USUARIO' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.

    El error nos esta informando de que la tabla se llama USUARIOS, por lo que ahora podemos escribir lo siguiente en el formulario de entrada:

              Usuario:Pedro
              Clave:' ; DROP TABLE USUARIOS ; --

    Con esta ejecución el usuario ha conseguido eliminar nuestra tabla de usuarios ...

Como protegerse de este tipo de ataques.

    Para protegerse de este tipo de ataques podemos (y debemos) tomar varias medidas.

  • Parametrizar las consultas utilizando comandos preparados. Con esto conseguimos evitar la ejecución de código no deseado. Es la mejor forma de protegernos. En muchos articulos recomiendan "reemplazar" las comillas simples y otros caracteres "peligrosos", pero este método es mucho mas seguro y fácil de implementar.

 
<%
sql = "Select * from USUARIOS where USUARIO=? and CLAVE=?"
 set cmd = Server.CreateObject("ADODB.Command")
 cmd.ActiveConnection = connection
 cmd.CommandText =sql
 cmd.Parameters(0).Value = usuario
 cmd.Parameters(1).Value = clave

 set rs = cmd.Execute()
%>

  • Conectar a la base de datos con usuarios que solo tengan permisos de lectura, de esta forma el atacante no tendrá permisos de ejecución. Esta es una tarea que debe realizar el DBA, y debemos tener usuarios de solo lectura para aquellas partes de nuestra aplicación que pensemos que pueden ser victimas de ataques.

    Saludos y hasta la proxima , DJK


 Versión para imprimir  Foros de consulta


Añadir comentario ... Para preguntar utiliza los foros
Autor:

Título:


Para preguntar utiliza los foros.



 Versión para imprimir

Seguridad en Internet - SQL Injections
Autor: Pedro Herrarte Sánchez
Visitas: 4027 Fecha de publicación: 07/06/2006
Pedro Herrarte, es consultor independiente, ofreciendo sercivios de consultoría, análisis, desarrollo y formación.

Posee mas de diez años de experiencia trabajando para las principales empresas de España.

Es especialista en tecnologías .NET, entornos Web, bases de datos (SQL Server y ORACLE) e integración de sistemas.

Es experto en desarrollo (C#, ASP.NET, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE).

Es fundador, diseñador y programador de www.devjoker.com.




18/08/2008 SQL Server 2008
Visitas: 39 | Comentarios: 0 | Archivo: Articulos
Categorias: Transact-SQL
Visitas: 131 | Comentarios: 0 | Archivo: Articulos
Categorias: C#|ADO.NET|LinQ
Visitas: 161 | Comentarios: 1 | Archivo: Articulos
Categorias: Humor
Visitas: 154 | Comentarios: 0 | Archivo: Articulos
Categorias: WCF
Visitas: 123 | Comentarios: 0 | Archivo: Articulos
Categorias: WCF
Visitas: 210 | Comentarios: 0 | Archivo: Articulos
Categorias: ASP.NET
Visitas: 277 | Comentarios: 5 | Archivo: Articulos
Categorias: ASP.NET
Visitas: 4990 | Comentarios: 4 | Archivo: Articulos
Categorias: C#|Transact-SQL|LinQ
Visitas: 602 | Comentarios: 1 | Archivo: Articulos
Categorias: Visual Studio
Visitas: 1402 | Comentarios: 1 | Archivo: Articulos
Categorias: Transact-SQL

Útimos temas recibidos en los foros ...
Y lo mismo en WEB por systemat ... [C#] 1 18/08/2008
Manual del minicom de Linux con fotos. por Meta ... [UNIX] 4 17/08/2008
PROGRAMACION por JUANMA ... [Visual Basic .NET] 1 19/08/2008
Conectar ASP con B.D Informix por Franco ... [ASP] 9 02/05/2007
Codigo salir por Jazmin ... [ASP.NET] 1 18/08/2008
EXPORTAR DATOS A ARCHIVOS PLANOS. por WIX ... [ORACLE] 10 06/08/2007
formulario por artdark ... [C#] 2 04/08/2008
Codigo salir por Jazmin ... [ASP.NET] 0 18/08/2008
cambiar de modo un gried view por ivan ... [ASP.NET] 0 18/08/2008
ayuda urgente porfavor por vicancer ... [ASP.NET] 0 18/08/2008
pollo por hajaj ... [Actualidad] 1 15/08/2008
DIOS TE BENDIGA por El You ... [WIN 98/NT/2000/XP] 1 16/08/2008

Access CGI JSP ORACLE UNIX
Actualidad HTML/DHTML/XHTML LINUX PHP Visual Basic .NET
ASP ISAPI MS DOS Power Builder Visual Basic 6.0
ASP.NET Java mySQL SQL WIN 98/NT/2000/XP
C# JavaScript Opinion SQL Server

devjoker  Te recomendamos además ...
08/09/2007 Funciones en Transact SQL    forma parte de...Tutorial de Transact SQL
12/01/2006 Introducción a PLSQL    forma parte de...Tutorial PL/SQL
08/07/2008 Fiddler - Indispensable para el desarrollo Web
13/08/2007 Reiniciar un campo identity en SQL Server
22/10/2005 Introducción SQL    forma parte de...Tutorial SQL
03/10/2006 Fundamentos de C#    forma parte de...Tutorial C#
19/09/2006 Recuperar datos BLOB de ORACLE
04/07/2007 ¿Cómo crear RSS?    forma parte de...Tutorial RSS
04/07/2007 ¿Cómo se usa el RSS?    forma parte de...Tutorial RSS
03/04/2008 LINQ con métodos Extensores y expresiones lambda    forma parte de...Linq y Métodos extensores

 

Encuesta
Si trabajas con .NET ¿Que entorno utilizas?
[Ver] [Votar]