Blue Core Research
Contactanos
Inyección SQL
La inyección SQL es uno de los vectores de ataque más conocidos y supone un importante desafío para la seguridad. Descubra cómo funciona la inyección SQL y los diferentes enfoques para solucionarla.

Introducción

La inyección SQL es uno de los vectores de ataque más conocidos y supone un importante reto para la seguridad. La única forma de comprender las ventajas y deficiencias de cada solución es comprender el problema y el enfoque que cada solución utiliza para resolverlo.

El Problema

La mejor manera de comprender el problema es mediante ejemplos. Para demostrar cómo funciona la inyección SQL, aquí hay un ejemplo de una aplicación sencilla.

Ejemplo de Aplicación

Account
0
First Name
John
Last Name
Doe
Last 4 of social
5555
Sumbit
SELECT card FROM cards WHERE
  account = 0 AND
  first = ’John’ AND
  last = ’Doe’ AND
  ssn = 5555

Supongamos que nuestra aplicación es una página web sencilla que permite a los representantes de atención al cliente ver los números de las tarjetas de crédito de los clientes que llaman.

Por motivos de seguridad, el representante debe introducir el número de cuenta del cliente, su nombre, apellidos y los cuatro últimos dígitos de su número de la seguridad social.

Cuando toda la información coincide con los datos del cliente, se muestran los números de las tarjetas de crédito utilizadas por el cliente.

Parece un diseño bastante seguro, ya que el representante de atención al cliente tiene que obtener la información de un cliente real para ver sus tarjetas de crédito. ¿Cómo podría un representante de atención al cliente utilizar este formulario para obtener información sobre cualquier otro cliente?

El problema no está en el diseño conceptual, sino en la implementación real del código.

Para que esta página funcione, la aplicación que se ejecuta dentro del servidor web necesita ejecutar un SQL contra la base de datos. Ese SQL podría parecerse al ejemplo anterior.

Sin embargo, este SQL parece ser el SQL correcto para ejecutar y no hay una forma aparente de obtener la información de la tarjeta de crédito sin introducir la información del cliente.

Entonces, ¿cuál es el problema con la implementación?

El Ataque

Account
John
First Name
Doe
Last Name
0 OR 1=1
Last 4 of social
0 OR 1=1
Sumbit
SELECT card FROM cards WHERE
  account = 0 AND
  first = ’John’ AND
  last = ’Doe’ AND
  ssn = 0 OR 1=1

Al completar el formulario de esta manera y ejecutar la sentencia SQL, la base de datos compara las condiciones con cada fila de la tabla.

Supongamos que la primera fila corresponde al cliente 1001, llamado JOE SMITH, con número de seguro social 5555:

  • ¿Es el cliente número 0? No, es… 1001
  • ¿El nombre es JOHN? No, es JOE.
  • ¿El apellido es DOE? No, es SMITH.
  • ¿El número de la Seguridad Social es 0? No, es 5555.
  • ¿Es 1 = 1? Sí, 1 siempre es igual a 1.

En SQL, el orden de las operaciones evaluará el AND antes del OR, dando como resultado algo como esto:

(FALSE and FALSE and FALSE and FALSE)
or
(TRUE)

El resultado final de esta comparación es VERDADERO. Esto significa que se mostrará el número de tarjeta de crédito de JOE SMITH.

Como esta condición se cumple en todas las filas de la tabla, se mostrarán todas las tarjetas de crédito.

Como completamos el formulario de una forma inesperada para el programador y contra la que no se protegió, logramos engañar a la aplicación para que nos mostrara todas las tarjetas de crédito de la base de datos.

La variación de cadena

La base de datos considerará ssn = ‘5555’ como una comparación válida y convertirá automáticamente la cadena ‘5555’ en el número 5555. Por lo tanto, si incrustamos el valor como una cadena, el resultado sería diferente. Corrijamos la aplicación para que ejecute este SQL:

SELECT card FROM cards WHERE
  account = 0 AND
  first = ’John’
  AND last = ’Doe’
  AND ssn = '5555'

En este caso, la base de datos devolverá un error si completamos el formulario con «0 OR 1=1», ya que no puede convertir esta cadena en un número. ¿Hemos evitado la inyección SQL?

Account
0
First Name
John
Last Name
Doe
Last 4 of social
0 OR 1=1
Sumbit
SELECT card FROM cards WHERE
  account = 0 AND
  first = ’John’ AND
  last = ’Doe’ AND
  ssn = 0 Or 1=1

Con esta ligera modificación, el ataque seguirá extrayendo todas las tarjetas de crédito porque ‘a’ siempre es igual a ‘a’.

Truncando el SQL

Account
0 OR 1=1 —
First Name
John
Last Name
Doe
Last 4 of social
5555
Sumbit
SELECT card FROM cards WHERE
  account = $account2 AND
  first = ’John’ AND
  last = ’Doe’ AND
  ssn = 5555

Otra complicación que un atacante podría enfrentar es si hay otra condición AND después del código inyectado. En el ejemplo anterior, inyectamos en el número de cuenta que tiene varias condiciones AND posteriores.

El doble guion (- -) en SQL comenta el resto de la línea, por lo que cualquier condición adicional se puede eliminar fácilmente.

En MySQL, # es otra forma de comentar el resto de la línea con el mismo efecto que —

Otra forma de agregar un comentario a una sentencia SQL es encerrándolo entre /* /. Si un comentario comienza, la mayoría de las bases de datos lo considerarán como tal hasta el final de la sentencia SQL (con cualquier número de líneas). Por lo tanto, agregar / en lugar de — también comentará el resto de la sentencia SQL.

Otra consideración en MySQL es que /*! */ no es un comentario, ya que el símbolo ! lo desactiva. Esto puede ser un método útil para eludir las medidas de seguridad que ignoran los comentarios.

Fragmentación de parámetros (HPF)

Account
0 OR/*
First Name
*/1/*
Last Name
*/=/*
Last 4 of social
*/1
Sumbit
SELECT card FROM cards WHERE
  account = $account2 AND
  first = ’$first2’ AND
  last = ’$last2’ AND
  ssn = $ssn2

Otra opción es comentar secciones enteras del SQL y dividir el ataque entre varios parámetros.

En SQL, cualquier texto entre /* y */ es un comentario y se ignora.

Lo bueno de este ataque es que no solo deshabilitó partes completas del SQL, sino que también dividió el ataque entre parámetros, lo que dificultó su detección por la tecnología WAF. Más sobre esto más adelante.

Dividiendo el SQL

Account
0
First Name
Doe
Last Name
*/=/*
Last 4 of social
1 UNION SELECT SSN FROM USERS
Sumbit
SELECT card FROM cards WHERE
  account = 0 AND
  first = ’John’ AND
  last = ’Doe’ AND
  ssn = $ssn2

¿Qué pasa si el formulario vulnerable no accede a la tabla o las columnas que buscamos? Supongamos que queremos leer la columna SSN de la tabla USERS, ya que esta contiene el número de la Seguridad Social completo y no solo los últimos 4 dígitos.

¿Cómo puede un formulario que lee la tabla cards mostrarnos información de una tabla completamente diferente?

La sentencia SQL anterior utiliza el operador UNION para combinar la salida de dos sentencias SQL diferentes en un único conjunto de resultados:

En este caso, la primera SELECT no devuelve datos, pero la segunda volcará toda la columna SSN de la tabla USERS. El operador de unión combinará ambas en un único conjunto de resultados y la aplicación mostrará todas las filas de la columna SSN como si fueran tarjetas de crédito.

Lote de SQL

Account
0
First Name
John
Last Name
Doe
Last 4 of social
0; CREATE LOGIN hacker WITH PASSWORD = ‘password’
Sumbit
SELECT card FROM cards WHERE
  account = 0 AND
  first = ’John’ AND
  last = ’Doe’ AND
  ssn = 0; CREATE LOGIN hacker WITH PASSWORD = 'password'

En Microsoft SQL Server y Sybase, las SQL se envían a la base de datos en lotes. Un lote es una secuencia de SQL enviada a la base de datos en una sola solicitud, y todas las solicitudes son lotes.

Puede usar un punto y coma para separar las SQL del lote:

SELECT c1 FROM t1; SELECT c2 FROM t2

Sin embargo, la semicolumna es opcional y este lote producirá el mismo resultado:

SELECT c1 FROM t1 SELECT c2 FROM t2

En estas bases de datos, la inyección SQL puede alcanzar un nivel de maldad completamente nuevo. El fragmento inyectado puede ejecutar un código SQL completamente diferente, lo que le permite cambiar datos, alterar la base de datos y más.

Este ejemplo asume que la aplicación está conectada a SQL Server con una cuenta con privilegios. Tenga en cuenta que el punto y coma es opcional, pero se utiliza para mayor claridad.

Al ejecutarse, no se devolverán las tarjetas de crédito, pero se creará un nuevo usuario llamado «hacker» en la base de datos con la contraseña «password».

Este método puede utilizarse para modificar datos, permisos y mucho más. Cualquier acción para la que la cuenta de la aplicación tenga privilegios puede realizarse mediante este tipo de ataque. El atacante puede incluso ejecutar el comando de apagado y apagar la base de datos.

Si el control total sobre la base de datos no es suficiente, SQL Server también cuenta con el procedimiento xp_cmdshell, que permite ejecutar comandos del sistema operativo, y xp_regread, que puede leer el registro. Esto otorga al atacante acceso completo al equipo.

Si bien las aplicaciones nunca deben usar una cuenta con privilegios en ninguna base de datos, esta regla cobra suma importancia en las bases de datos de SQL Server. Las aplicaciones que utilizan bases de datos de SQL Server nunca deben usar una cuenta con privilegios. Desafortunadamente, muchas aplicaciones en SQL Server utilizan la cuenta SA, que cuenta con privilegios elevados.

Variaciones

Hasta ahora, hemos hablado principalmente del uso de OR 1=1. Este es el ejemplo clásico que siempre se usa y podría dar la impresión de que si una sentencia SQL no contiene esta expresión, no hay inyección SQL.

En realidad, existen infinitas variaciones de condiciones que siempre son verdaderas, y esto es solo una pequeña muestra.

Comenzaremos con ejemplos triviales que usan operadores simples:

ExpresiónExplicación
17 != 2117 siempre es diferrente a 21
99 < 10099 siempre es menor que 100
9-1 > 39-1 siempre es mayor que 3
‘ABC’ = ‘ABC’La cadena ‘ABC’ siempre es idéntica a ‘ABC’
‘hello’ != ‘world’La cadena ‘hola’ siempre es diferente de la cadena ‘mundo’

También podemos utilizar algunas funciones de base de datos para crear expresiones ligeramente más complejas:

ExpresiónExplicación
‘XYZ’ like ‘%Y%’XYZ contiene una Y
‘B’ in (‘A’, ‘B’, ‘C’)B está en la lista
7 in (select 7)7 está en el conjunto de resultados
translate(‘AB’,’AB’,’XY’) = ‘XY’Reemplazar A por X y B por Y en AB da como resultado XY

Sin embargo, todos estos ejemplos utilizan literales (constantes). Si tuviéramos una herramienta lo suficientemente inteligente como para calcular todas las expresiones que la base de datos puede ejecutar, podría determinar que estas expresiones siempre son verdaderas.

Esto significa que, en teoría, sería posible detectar que los ejemplos anteriores son inyecciones SQL. Pero eso solo significa que debemos avanzar un poco más.

Las siguientes expresiones utilizan valores de columna y, por lo tanto, ninguna herramienta puede calcularlas para determinar que siempre son verdaderas. Es imposible distinguir estas expresiones de la lógica de la aplicación.

ExpresiónExplicación
last != ‘XYZ’el apellido no es XYZ
ssn > 0SSN es mayor que 0
id not in (0, 1, 2)El ID no es 0, 1 o 2
first != lastEl nombre y el apellido son diferentes

Aunque estas expresiones probablemente siempre serán ciertas, es imposible determinarlo sin comprender los datos de cada columna. Se profundizará en este tema en la sección sobre análisis estático.

Entrada no trivial

Todos los ejemplos anteriores introdujeron datos en los campos del formulario. Esta es la forma más sencilla de interactuar con la aplicación, pero no es la única.

El formulario HTML anterior suele enviar la consulta al servidor web de la aplicación mediante una solicitud GET o POST. Una solicitud GET podría ser similar a esta:

…/cards?id=0&first=JOHN&last=DOE&ssn=5555

Probablemente hayas visto cadenas como esa en la URL de tu navegador web. La misma solicitud GET también se puede enviar mediante AJAX de una forma que no es visible en la URL, pero que se puede ver con la misma facilidad en la consola de desarrollador (prueba a pulsar F12 en tu navegador web).

Las solicitudes POST suelen tener el mismo formato que las solicitudes GET, pero no se envían en la URL. También se pueden ver fácilmente en la consola de desarrollador de cualquier navegador web.

Cuando los atacantes piratean, suelen enviar solicitudes GET y POST directamente. Esto les permite manipular los campos de formas que el formulario de solicitud podría no permitir.

Estas entradas no triviales son ligeramente más difíciles de identificar y modificar, y por lo tanto, más difíciles de explotar. Sin embargo, esta falta de accesibilidad también significa que es poco probable que los desarrolladores las protejan o prueben adecuadamente.

Algunos ejemplos de información que no se puede editar en un formulario pero que se puede cambiar en una solicitud GET o POST (entre otras maneras):

  • Campos de entrada ocultos: son campos de entrada invisibles para el usuario. Las aplicaciones los utilizan para almacenar información contextual sobre el estado de la aplicación o el flujo de datos del usuario. Aunque el usuario no puede ver estos campos en pantalla, modificar su contenido es sencillo. Por ejemplo, un ID de sesión podría almacenarse en un campo oculto y la aplicación podría usarlo en una consulta a la base de datos.
  • Campos de selección: son cuadros combinados de opción única o de selección múltiple. Aunque el usuario solo puede seleccionar entre las opciones mostradas, un atacante puede enviar cualquier valor. Por ejemplo, si solo se puede elegir entre dos opciones que envían un valor, 0 o 1, un atacante puede enviar el valor 0 o 1=1.
  • Enlaces: A menudo hacemos clic en enlaces, botones, árboles, imágenes y otros componentes de las aplicaciones web. Estos enlaces suelen tener valores incrustados, que un atacante puede manipular fácilmente. Por ejemplo, el enlace «Página siguiente» que vemos a menudo tendría incrustado el primer número de elemento de la página siguiente (p. ej., start=10). Ese primer número de elemento podría modificarse para incluir una inyección SQL.
  • Cookies: Las cookies son otra forma de almacenar información de estado en el navegador web y enviarla al servidor web. Por ejemplo, este es el lugar estándar que las aplicaciones usan para guardar los ID de sesión.

Este tipo de entradas nunca son probadas por el control de calidad ni por los usuarios habituales, y la mayoría de los sistemas automatizados de detección de vulnerabilidades tampoco las prueban. Esto significa que las fallas en este tipo de entradas pueden permanecer latentes durante años sin siquiera ser detectadas o abordadas.

Como resultado, estas entradas no triviales tienden a ser mucho más vulnerables y proporcionan un terreno fértil para ataques dirigidos por parte de hackers experimentados.

Contaminación de parámetros (HPP)

Un tipo de ataque que solo puede llevarse a cabo manipulando las solicitudes GET/POST es la contaminación de parámetros. Por ejemplo, ¿qué ocurre si la aplicación mencionada recibe dos campos de SSN en la solicitud en lugar de uno? En otras palabras, la solicitud GET se vería así:

?id=0&first=JOHN&last=DOE&ssn=5555&ssn=7777

La respuesta depende de la pila de tecnología utilizada por la aplicación y de los métodos empleados para extraer los parámetros. Algunas tecnologías devolverán una lista separada por comas de los parámetros duplicados. Por lo tanto, la solicitud anterior devolverá:

5555,7777

Esto crea una oportunidad para un ataque similar a la fragmentación de parámetros (HPF), pero sin requerir múltiples parámetros ni conocer su orden en el SQL. Por ejemplo, enviando estos 4 números de seguro social (divididos en líneas para mayor claridad):

…/cards?id=0&first=JOHN&last=DOE
&ssn=0 OR /*
&ssn=*/ 1 /*
&ssn=*/ = /*
&ssn=*/ 1

El resultado será este SQL:

SELECT card FROM cards WHERE
   account = 0 AND
   first = ’JOHN’ AND
   last = ’DOE’ AND
   ssn = 0 OR /*,*/ 1 /*,*/ = /*,*/ 1

Se trata de un ataque de inyección SQL fragmentado que utiliza un único parámetro.

Sin palabras clave

Account
ACCOUNT/*
First Name
John
Last Name
Doe
Last 4 of social
1
Sumbit
SELECT card FROM cards WHERE
  account = $ACCOUNT2 AND
  first = ’John’ AND
  last = ’Doe’ AND
  ssn = 1

Hasta ahora, todos los ataques utilizaban palabras clave SQL como OR y UNION. Aunque son palabras simples en inglés que podrían aparecer en datos normales, hacen que la entrada parezca sospechosa.

Pero con un poco de investigación y esfuerzo, es posible crear una inyección SQL sin palabras clave ni espacios.

En este ejemplo, simplemente comprobamos si una columna es igual a sí misma y comentamos el resto del SQL. Dado que la cuenta siempre es igual a sí misma, este SQL devolverá todas las tarjetas de la tabla.

Truncamiento sin comentarios

Account
1 OR 1=1 OR 1=1
First Name
John
Last Name
Doe
Last 4 of social
1
Sumbit
SELECT card FROM cards WHERE
  account = $ACCOUNT2 AND
  first = ’John’ AND
  last = ’Doe’ AND
  ssn = 1

Otro motivo recurrente en estos ejemplos ha sido el uso de comentarios. Muchas veces los hemos usado para eliminar partes no deseadas del SQL. Pero hay otra manera.

Resaltamos el OR en azul. En el orden de precedencia, los OR van al final, por lo que cualquier operación separada por un OR se evalúa por separado. La parte roja siempre se evalúa como verdadera, por lo que toda la cláusula WHERE siempre es verdadera.

Entradas numéricas engañosas

Account
cast(1 as varchar(10)) OR 1=1
First Name
John
Last Name
Doe
Last 4 of social
1
Sumbit
SELECT card FROM cards WHERE
  account = cast(1 as varchar(10)) OR 1=1 AND
  first = ’John’ AND
  last = ’Doe’ AND
  ssn = 1

Una estrategia para burlar algunos sistemas de defensa es crear confusión sobre la naturaleza del parámetro.

El parámetro «Cuenta» no parece una entrada numérica, y las defensas automáticas que buscan validarlo como una cadena lo considerarán seguro para su ejecución, ya que no tiene etiquetas (‘) que la terminen.

cast() es un operador estándar de base de datos que convierte el número en una cadena. La base de datos considerará esta entrada válida y volverá a convertir la cadena en un número para compararla con la cuenta.

Pantallas de inicio de sesión

Username
admin’–
Password
x
Login
SELECT $field FROM users WHERE
  $w

Las pantallas de inicio de sesión también son vulnerables a ataques de inyección SQL. Hay dos maneras de que la aplicación verifique a un usuario, y cualquiera de ellas puede ser vulnerada.

Consulta valida contraseña

Una opción es que la consulta valide la contraseña. Si la contraseña coincide con la fila, se devuelve; de lo contrario, no se devuelve nada.

El SQL contendrá el hash o una función hash en la cláusula where. Al completar la pantalla de inicio de sesión, como en el ejemplo anterior, la validación de contraseña del SQL se desactiva.

Este doble guión (- -) comentará el resto del SQL y se devolverá la fila para admin, lo que sugiere que la contraseña ha sido autenticada.

Consulta recupera contraseña

Username
‘ union select ‘5f4dcc3b5aa765d61d8327deb882cf99
Password
password
Login
SELECT password FROM users WHERE
  username = '' union
  select '5f4dcc3b5aa765d61d8327deb882cf99'

Otra opción para validar contraseñas es recuperar el hash de la base de datos y validarlo en el código.

Esta consulta SQL devolverá el MD5 de la palabra «contraseña». Al comparar este MD5 con la contraseña proporcionada, coincidirán. Simplemente devolvemos el hash de la contraseña deseado, en lugar del que esté almacenado en la base de datos.

Introducción a las Soluciones

Es importante comprender que la inyección SQL es, fundamentalmente, la explotación de una falla de seguridad en el código. Al igual que no existen garantías de que el código no contenga errores, es difícil garantizar que no presente vulnerabilidades de inyección SQL. Sin embargo, como con cualquier otro error, la mejor solución es corregir la falla en el código. La alternativa es intentar prevenir, detectar o dificultar la explotación de las vulnerabilidades, pero todos estos enfoques tienen limitaciones.

En las siguientes secciones se revisarán diferentes enfoques y se analizarán las ventajas y limitaciones de cada uno. Pero antes de profundizar en los detalles, hagamos un análisis general para comprender el contexto.

Soluciones en el Código

Como se mencionó anteriormente, la mejor solución es contar con código de alta calidad y técnicas de codificación adecuadas que eviten la posibilidad de una inyección SQL.

La mejor manera de evitar un ataque de inyección SQL es usar variables de enlace. Esta es la solución ideal y previene por completo las inyecciones SQL. Otros métodos menos robustos incluyen el escape y la validación de entrada. También se recomienda reducir los informes de errores del cliente.

Más adelante, se explicarán más sobre estas técnicas, su valor, sus limitaciones y cómo implementarlas.

Soluciones de bases de datos

La inyección SQL es, en definitiva, un ataque a bases de datos que aprovecha la flexibilidad de SQL. Por lo tanto, la solución más obvia es la base de datos.

Varias tecnologías pueden ayudar a detectar o prevenir la inyección SQL en la base de datos. El problema con la mayoría es que no son efectivas. A diferencia de la mayoría de las demás soluciones de bases de datos para detectar la inyección SQL, la tecnología única de Core Audit es extremadamente efectiva.

Más adelante, hablaremos más sobre estas tecnologías de bases de datos y sus diferencias.

Firewall de Aplicaciones Web (WAF)

La dificultad para identificar la inyección SQL a nivel de base de datos dio lugar a una nueva categoría de productos: los Firewalls de Aplicaciones Web (WAF).

La idea es que sea más fácil detectar el ataque de inyección SQL al examinar la entrada de la aplicación que al examinar el SQL enviado a la base de datos.

Es una buena teoría, pero solo funciona con ejemplos simples o específicos. Al intentar prevenir todos los tipos de ataques de inyección SQL descritos en este documento, el problema se vuelve insalvable. Más adelante se abordará este tema.

Firewall en la aplicación

Una nueva tecnología desarrollada por Blue Core Research busca llevar la tecnología WAF al siguiente nivel e integrarla en la aplicación.

El Agente Java de Core Audit proporciona datos de auditoría detallados sobre todo lo que ocurre en la aplicación. También puede aplicar reglas de bloqueo de tipo firewall a toda la aplicación o a áreas sensibles del código.

Un Firewall en la aplicación puede aprovechar el contexto y la información disponibles solo dentro de la aplicación para proteger correctamente los métodos adecuados.

Detectar

Esta amplia gama de enfoques no solo difiere en su tecnología y eficacia, sino también en el valor que aportan. Sin embargo, existe una correlación inversa entre valor y eficacia.

Los enfoques de detección buscan alertarle de una posible inyección SQL. La desventaja es que no la bloquean y, además, deberá tomar medidas contra el atacante y corregir el código.

El valor percibido parece ser menor, pero la ventaja es que la detección se puede ajustar para que sea sensible y proporcione un mecanismo bastante eficaz. Un potente motor de detección como el de Core Audit probablemente le notifique de cualquier intento de inyección SQL.

Prevenir

Los enfoques preventivos se dividen en dos categorías principales: bloqueo y corrección. Dependiendo del tipo de solución, ambas opciones pueden estar disponibles, como en el Agente Java de Core Audit.

La ventaja del bloqueo es que se previenen los intentos de inyección SQL que el motor de bloqueo puede reconocer.

Si bien existen diferencias significativas entre los distintos productos, ninguno puede afirmar que ignore automáticamente toda la actividad legítima ni bloquee todos los ataques. Más adelante se hablará de esto.

Además de su eficacia limitada, las soluciones preventivas corren el riesgo de bloquear la actividad legítima. Cuanto más versátil sea la actividad y más estricto el bloqueo, mayor será la probabilidad de que se bloquee alguna actividad válida.

El Agente Java de Core Audit, por ejemplo, ofrece una calibración entre métodos flexibles y estrictos para que pueda aplicar el nivel de filtrado adecuado a la actividad relevante.

Sanitizar

Finalmente, algunas soluciones buscan solucionar el problema sin bloquearlo. Con estas soluciones, se eliminan las inyecciones maliciosas de la entrada y se permite su ejecución segura. Core Audit también cuenta con esta capacidad.

Si bien esta es una publicidad muy atractiva, en muchas soluciones implica el alto costo de introducir vulnerabilidades adicionales. El problema es que un atacante puede diseñar un ataque que aproveche el proceso de sanitización como parte del ataque.

Esto significa que, además de la eficacia limitada de la detección de inyecciones SQL, el uso de la sanitización puede reducir la eficacia de la solución al ofrecer al atacante herramientas adicionales para eludir la seguridad. Más adelante se hablará de esto.

Escapando de la jaula de parámetros

Al observar los diversos ejemplos, resulta evidente que la inyección SQL consiste en modificar el contrato SQL escapando de la jaula de parámetros.

Si el parámetro es una cadena, la inyección SQL deberá terminarla antes de poder modificar el SQL. Esto suele implicar incluir una etiqueta (‘) en la entrada.

Los parámetros numéricos terminan con espacios en blanco (espacio, tabulación, nueva línea, etc.) u otros caracteres que no forman parte del literal (por ejemplo, una /).

Detectar un escape de la jaula de parámetros es un método para reconocer la inyección SQL en los firewalls de aplicaciones, pero depende de la correcta identificación del tipo de parámetro.

Otro método común es la identificación de palabras clave sospechosas o caracteres especiales. Este método también presenta limitaciones significativas.

Soluciones en el Código y Buenas Prácticas

Como se mencionó anteriormente, la mejor solución es tener un buen código. Las técnicas de codificación adecuadas pueden reducir e incluso eliminar el riesgo de inyección SQL. Esta sección las analizará en detalle.

Vincular variables

Todos los ataques de inyección SQL implican escapar de la jaula de parámetros mencionada anteriormente. Afortunadamente, todas las bases de datos incluyen una API completa para evitarlo. Se denominan variables de enlace.

Las variables de enlace permiten enviar los parámetros por separado del SQL en lugar de incrustar las constantes. Por ejemplo, el SQL anterior utilizado en los ejemplos se vería así con variables de enlace:

SELECT card FROM cards WHERE
  account = :1 AND
  first = :2 AND
  last = :3 AND
  ssn = :4

Cuando este SQL se envía a la base de datos, el programador también debe enviar los valores de las variables de enlace (:1, :2, :3, :4).

Escribir SQL de esta manera evita que la base de datos malinterprete parte del valor como parte de la construcción SQL. Los valores pueden contener cualquier carácter y la base de datos no se confundirá.

El uso de variables de enlace también ofrece una ventaja en el rendimiento. Cuando el mismo SQL se ejecuta varias veces con diferentes variables de enlace, solo se debe analizar una vez. Ese es, de hecho, el propósito original de las variables de enlace.

Desafortunadamente, reescribir toda la aplicación para usar variables de enlace puede ser costoso, difícil o totalmente impráctico.

Entrada de escape

El enfoque más común para corregir el código de la aplicación es escapar todos los campos de entrada. Por ejemplo, si un campo de entrada contiene una etiqueta (‘), reemplácela con dos etiquetas (‘ ‘). La comilla escapada puede incrustarse en una sentencia SQL sin provocar un ataque de inyección.

Escapar la entrada John O’Brian en nuestro ejemplo generará esta sentencia SQL:

SELECT card FROM cards WHERE
  account = 0 AND
  first = ’John’ AND
  last = ’O''Brian’ AND
  ssn = 5555

Escapar la entrada es solo una parte de la solución, ya que solo resuelve el problema de la entrada de cadena. La entrada numérica requiere un enfoque diferente, que se menciona más adelante.

Si bien este no es el mejor método para prevenir la inyección SQL, es el más utilizado. Esto se debe a su impacto relativamente bajo en el código y, en consecuencia, a sus menores costos de implementación.

Entrada numérica

Corregir la entrada numérica es, por un lado, una solución muy sencilla. Sin embargo, esta solución debe implementarse individualmente para cada entrada numérica, lo que puede resultar lento, difícil y costoso.

Todo lenguaje de programación contiene una función para convertir cadenas en números y un método para incrustar esos números en una cadena. Al convertir la entrada en un número antes de incrustarla en la cadena SQL, garantizamos que sea un número real.

Por ejemplo, un código inseguro en PHP podría verse así:

$sql .= " id= ".$_GET["ssn"];

Aunque la versión segura se ve así:

$sql .= " id= ".intval($_GET["ssn"]);

$_GET[«ssn»] lee el parámetro GET ssn y al envolverlo en intval() se garantizará que sea un número.

En Java, lo inseguro se ve así:

sql += " id = "+ssn;

Mientras que la versión segura es esta:

sql += " id = "+Integer.parseInt(ssn)

Se pueden crear ejemplos similares para cualquier lenguaje de programación, desde Python hasta C. La idea es siempre la misma: convertir a un número y luego volver a una cadena.

Cabe destacar que existen ligeras diferencias en el funcionamiento de esta técnica en distintos lenguajes, las cuales dependen del funcionamiento de la función de conversión.

Por ejemplo, la función intval() en PHP convertiría parte de la cadena si fuera posible; por ejemplo, la cadena «7 OR 1=1» se convertiría a 7. Si no se pudiera analizar la entrada, la función devolvería el valor 0.

Sin embargo, en Java, la función Integer.parseInt() intentaría convertir la cadena completa a un número y cualquier obstáculo provocaría una excepción.

Independientemente de las diferencias, todas estas implementaciones son seguras y ninguna permitiría que una inyección SQL pasara por el parámetro numérico.

Validación de entrada

La validación de entrada consiste en garantizar que la entrada sea aceptable y se ajuste a los parámetros operativos de la función. Es un concepto mucho más amplio que detener la inyección SQL, cuyo objetivo es prevenir diversos tipos de errores, incluyendo otros tipos de ataques.

Debido a su naturaleza amplia, es difícil considerar que el código que realiza la validación de entrada sea resistente a la inyección SQL. La validación de entrada podría incluir pruebas que garanticen que las cadenas solo tengan etiquetas de escape (‘) y que los números contengan números válidos. Sin embargo, estas pruebas podrían fácilmente no incluirse en las pruebas de validación de entrada.

Por ejemplo, considere este pequeño fragmento de código PHP:

if ($_GET['ssn'] > 0 &&
$_GET['ssn'] < 9999) return;

$sql .= " id= ".$_GET["ssn"];

Este código comprueba que el número de serie del servidor (ssn) esté entre 0 y 9999 y rechaza cualquier entrada que no esté dentro del rango. Si bien parece un código seguro, enviar «7 OR 1=1» omitirá la prueba y provocará una inyección SQL.

Esto se debe a que, para realizar la comparación, PHP debe convertir la cadena de entrada en un número. Es como si cada expresión $_GET[‘ssn’] de la sentencia if() estuviera encapsulada por la función intval(). Por lo tanto, «7 OR 1=1» se convertirá al número 7, que se encuentra dentro del rango válido.

Por lo tanto, si se utiliza la validación de entrada para prevenir la inyección SQL, es importante exigir y comprobar específicamente que las entradas sean válidas desde el punto de vista de la inyección SQL. Esto generalmente implica escapar la entrada como se describió anteriormente.

Mensajes de error e inyección ciega

Los desarrolladores de aplicaciones suelen mostrar al usuario los errores que han detectado en la base de datos. Si bien esta información es inútil para el usuario, es valiosa para los desarrolladores que necesitan depurar el problema.

Sin embargo, esta misma información también es valiosa para un hacker que desee realizar un ataque de inyección SQL. Los mensajes de error de la base de datos pueden contener fragmentos de SQL y otras indicaciones que pueden ayudar al hacker a optimizar el ataque.

Para no tener estos mensajes de error de la base de datos, el hacker debe realizar lo que se conoce como inyección ciega. Esto implica técnicas más complejas y difíciles que intentan obtener información sin ver los mensajes de error de la base de datos.

Una de estas técnicas consiste en usar condiciones if() que invocan una función de suspensión (p. ej., waitfor) si son verdaderas. En otras palabras, se puede determinar si algo es verdadero o no en función del tiempo que tarda la consulta en completarse.

En resumen, la inyección ciega es más compleja y no hay razón para mostrar mensajes de error a los usuarios. Cuando un desarrollador necesita depurar un problema, siempre puede habilitar los mensajes de error para un escenario específico mientras realiza su investigación.

Detección de errores y vulnerabilidades

La mayoría de las aplicaciones tienen muchas páginas con aún más campos de entrada, y la mayoría de los hackers son demasiado perezosos para probarlos todos. Por ello, utilizan herramientas de escaneo que revisan cada entrada de cada página e intentan introducir el tipo de entrada que podría provocar que el código vulnerable devuelva un error.

Si ciertos tipos de entrada provocan un error en la aplicación, hay buenas razones para investigar más a fondo la vulnerabilidad de esa página.

Es importante recordar que este análisis sobre errores y vulnerabilidades asume que los hackers deben «experimentar» en la aplicación en vivo. Los hackers que tengan otro tipo de acceso al software de la aplicación lo utilizarán para detectar vulnerabilidades y aprender a explotarlas.

Otros tipos de acceso incluyen:

  • Software disponible para descargar e instalar
  • Acceso a sistemas no productivos (desarrollo, control de calidad, preproducción, etc.)
  • Acceso al código fuente o software libre

Esto nos lleva a varias conclusiones interesantes:

  • No muestre errores a los usuarios. Se quejarán si no obtienen datos. Mostrar números o mensajes de error crípticos no mejora su experiencia.
  • Los errores son útiles para los desarrolladores que necesitan depurar el problema y para los hackers que buscan vulnerabilidades en la aplicación. No mostrar errores es una forma de ocultar vulnerabilidades en el código.
  • Supervise errores en la base de datos. Cuando funcionan correctamente, las aplicaciones no deberían generar errores. Sin embargo, cuando los hackers intentan localizar código vulnerable y explotarlo, es probable que vea errores en la base de datos.
  • Si le preocupa la inyección de SQL, debe estar especialmente atento a los errores que involucran SQL no válido. Esta es una de las muchas cosas que Core Audit puede ayudarle a lograr.
  • Ejecute la herramienta de escaneo usted mismo. Las herramientas de escaneo de vulnerabilidades que utilizan los hackers están disponibles gratuitamente en internet. Ejecutar estas herramientas en su aplicación le mostrará al menos algunas vulnerabilidades en su código.

Soluciones de bases de datos

La inyección SQL es, en definitiva, un ataque a bases de datos que aprovecha la flexibilidad de SQL. Esta sección analizará diversas tecnologías que pueden ayudar a detectar o prevenir la inyección SQL en la base de datos.

Análisis SQL estático

El análisis SQL es la tecnología más antigua que intentaba detectar la inyección SQL. Las graves limitaciones de esta tecnología dieron origen a la tecnología WAF.

El análisis estático busca analizar SQL para identificar expresiones sospechosas en la cláusula where. El ejemplo clásico de OR 1=1 siempre será detectado por estas herramientas, pero ¿qué ocurre con las más complejas?

La sección anterior sobre variaciones es un buen punto de partida para explorar las ventajas de un analizador SQL estático.

Ningún analizador estático admite una gama tan amplia de operadores, funciones y expresiones. Pero incluso si lo hiciera, seguiría limitado a expresiones que utilizan literales.

Las expresiones que aprovechan los nombres de columna (como first != last) o SQL Batch están fuera de los límites teóricos de los analizadores estáticos y no podrían detectarlos.

Una lista corta de expresiones que podrían ser identificadas por los analizadores estáticos incluye:

  • Operadores: un analizador SQL estático necesita una lista completa de todos los operadores de la base de datos, incluyendo +, -, *, /, =, !=, <, <=, >, >=, <>, IN, NOT IN, ANY, SOME, ALL, BETWEEN, LIKE, etc.
  • Funciones: un analizador SQL estático necesita una lista completa de todas las funciones de la base de datos, incluyendo la manipulación de cadenas (Concat, Substr, Lower, Upper, Trim, Replace, Translate, etc.), funciones numéricas (Ceil, Round, Floor, Trunc, Mod, etc.), funciones de caracteres, funciones de fecha, funciones de conversión, etc.
  • Expresiones: un analizador SQL estático necesita evaluar las expresiones de la misma forma que lo haría la base de datos, incluyendo condiciones if, subconsultas, etc.

Intención de IA y SQL

Las soluciones más avanzadas que los analizadores estáticos utilizan aprendizaje automático e IA para diferenciar entre un SQL «bueno» y uno «malo». Estas se basan en un análisis complejo del lenguaje que busca comprender la intención de un SQL.

Es difícil determinar la eficacia de esta tecnología, ya que depende de que cada cliente le enseñe qué es bueno y qué no en su entorno particular.

Como resultado, cualquier SQL mal clasificado puede atribuirse simplemente a que el cliente aún no lo ha enseñado. De igual manera, cualquier inyección SQL detectada no implica que la siguiente también lo sea. Simplemente forma parte de la naturaleza impredecible de la IA.

Sin embargo, es difícil imaginar que incluso la mejor IA, enseñada por el cliente más diligente, pueda detectar OR first != last como una inyección SQL, ya que puede ser una parte legítima de la lógica de la aplicación.

Análisis de Anomalías

Blue Core Research desarrolló una tecnología única para detectar la inyección SQL. A diferencia de los analizadores estáticos y la IA, no intentamos comprender el SQL. Como hemos demostrado anteriormente, la realidad es que es imposible hacerlo bien.

Nuestra solución para la detección de la inyección SQL consiste en aprovechar nuestra tecnología de captura completa y nuestra tecnología de repositorio para crear una lista de todas las construcciones SQL que se ejecutan en la base de datos.

Dado que las aplicaciones repiten las mismas SQL una y otra vez, con el tiempo podemos aprender todas las SQL que utiliza la aplicación. Solo queda identificar las construcciones SQL que no hemos visto antes y marcarlas como posibles intentos de inyección SQL.

Por ejemplo, si nunca hemos visto que la aplicación ejecute una SQL específica con OR first != last en la cláusula where, le alertaremos de un posible intento de inyección SQL cuando lo detectemos.

El Análisis de Anomalías es también la única tecnología que siempre podrá detectar con éxito la inyección de una SQL completa mediante un lote. Este tipo de inyección es especialmente difícil de detectar porque no hay nada sospechoso en la SQL inyectada en sí. Lo único sospechoso es que esta SQL sea algo que la aplicación nunca hace. El Análisis de Anomalías lo detectará fácilmente.

El motor de Análisis de Anomalías de Core Audit puede hacer mucho más que identificar inyecciones SQL, pero esa es solo una ventaja más de esta tecnología. El Análisis de Anomalías es la tecnología más eficaz para detectar inyecciones SQL.

Firewall de aplicaciones web (WAF)

Como se mencionó anteriormente, el firewall de aplicaciones web (WAF) es una tecnología que surgió para abordar la amenaza de la inyección SQL. Comenzó cuando la única tecnología alternativa en ese momento era el análisis SQL estático, cuya ineficacia se demostró rápidamente.

Algunos proveedores llegan incluso a afirmar que pueden solucionar el problema de la inyección SQL sin modificar el código de la aplicación. Estas afirmaciones resultan muy atractivas para los clientes, pero son totalmente falsas. Estos proveedores comercializan sus soluciones como WAF, que incluye la palabra «Firewall» en el título y da a los clientes una falsa sensación de seguridad.

La idea detrás del WAF era que, si bien es imposible detectar la inyección SQL mediante el análisis estático del SQL enviado a la base de datos, debería ser posible detectarla al realizar un análisis estático de la entrada enviada a la aplicación. Es una buena teoría, pero el análisis que realizaremos a continuación demostrará que es incorrecta.

Concepto WAF

El concepto detrás de WAF es examinar la entrada del usuario antes de incorporarla al SQL. La idea es que un fragmento de SQL parezca sospechoso en la entrada del usuario, pero imposible de detectar una vez que se integre en el SQL completo.

Por ejemplo, tener OR first!=last en la cláusula where de un SQL podría ser una parte normal de la lógica de la aplicación e imposible de distinguir. Sin embargo, esa frase resultaría altamente sospechosa en la entrada normal del usuario.

Muchos hackers son perezosos y utilizan herramientas de análisis de inyección SQL. Estas herramientas revisan cada parámetro de cada página en busca de posibles vulnerabilidades. Por consiguiente, muchas implementaciones de WAF pasaron de proteger contra la inyección SQL a detectar el tipo de entrada inusual que generan estas herramientas. Esto no constituye protección contra la inyección SQL ni es efectivo, ya que existen muchas herramientas (incluidas las personalizadas).

Sin embargo, esto plantea una pregunta interesante: ¿por qué comprar un WAF que compara la entrada del usuario con patrones conocidos en las herramientas de análisis cuando se pueden encontrar todas esas vulnerabilidades uno mismo? Basta con ejecutar una herramienta de análisis de inyección SQL. Estas herramientas están disponibles en Internet de forma gratuita.

Este concepto plantea varios problemas fundamentales:

  • La inyección SQL no tiene por qué parecerse a un fragmento SQL; puede ser tan simple como «id –» (véase la sección sobre palabras clave). No necesita una palabra clave como OR, UNION, etc. No necesita símbolos especiales como = o !=. Podría ser algo que engañe incluso a una inspección humana de la entrada.
  • Falta de gramática: a diferencia de las SQL, la entrada del usuario no sigue una gramática predecible. No hay forma de saber qué significa la entrada ni por qué la introdujo el usuario. Esto hace que cualquier tipo de análisis estático sea extremadamente limitado y se base completamente en heurísticas, firmas y patrones de búsqueda.
  • Los distintos parámetros tienen distintos significados: la entrada del usuario varía mucho entre los distintos parámetros de la aplicación y entre todas las aplicaciones. A veces es un número de página, a veces una solicitud de búsqueda y a veces el nombre de una persona. Por lo tanto, es difícil definir reglas que se cumplan siempre para cualquier entrada.
  • La seguridad depende del código: si bien algunos parámetros pueden ser vulnerables a las inyecciones SQL, otros pueden gestionarse correctamente y ser seguros. La entrada O’BRIAN podría ser sospechosa porque tiene una etiqueta (‘) y, por lo tanto, intenta buscar vulnerabilidades en el código. Al mismo tiempo, podría ser segura si el código gestiona esta entrada correctamente.

Métodos y desafíos de WAF

Todas las soluciones WAF se enfrentan a los mismos desafíos básicos. La diferencia entre las herramientas radica en cómo equilibran dichos desafíos y la calidad de su implementación.

Tipo de parámetro

Como se mencionó anteriormente, la inyección SQL consiste en escapar de la estructura de parámetros. Sin embargo, esta estructura depende del tipo de parámetro. Para escapar de la estructura de un parámetro textual, se necesita una etiqueta (‘). Para escapar de la estructura de un parámetro numérico, se necesita un carácter delimitador literal, como un espacio, una barra, etc. Los parámetros numéricos también pueden reemplazarse por expresiones que modifican estas reglas.

Detectar el tipo de parámetro puede no ser tan sencillo como parece, considerando problemas como las entradas numéricas engañosas mencionadas anteriormente.

Si impidiéramos cualquier carácter que no sea una letra o un dígito, podríamos prevenir por completo la inyección SQL. Sin embargo, esto significa que, por ejemplo, nadie puede introducir un espacio en la entrada de la aplicación. Esto no supone un problema para la entrada numérica, pero sí para la textual.

Al determinar el tipo de parámetro, un WAF puede aplicar diferentes filtros a distintos tipos de parámetros y permitir una gama más amplia de entradas, lo que aumenta el riesgo de inyección SQL.

Caracteres especiales

El problema del tipo de parámetro se extiende a varios caracteres especiales que pueden usarse en la inyección SQL, así como en otros tipos de inyecciones (por ejemplo, inyecciones de nombres de archivo como LFI, RFI, etc.).

Existen muchos caracteres especiales, y al basarnos únicamente en el filtrado de caracteres especiales, bloquearemos rápidamente muchos tipos de entradas válidas de la aplicación.

Ejemplos de caracteres especiales:

  • Los comentarios pueden ser un guion doble (- -), un /* y, en MySQL, también un hashtag (#).
  • Los paréntesis pueden ser una llamada a una función o una subconsulta.
  • Las cadenas terminan con una etiqueta (‘), pero en MySQL, también pueden ir entre comillas dobles («).
  • Los literales numéricos terminan con espacios en blanco (espacio, CR, LF, Tab), una barra diagonal (/), un guion (-) y muchos otros caracteres.
  • Un punto y coma (;) puede terminar una consulta SQL en un lote.

Palabras Clave

La otra estrategia consiste en filtrar palabras clave que aparecen en SQL, como OR y UNION. Sin embargo, en la inyección por lotes, el punto y coma (;) es opcional y se puede iniciar un nuevo SQL en cualquier momento. Esto significa que también es necesario filtrar palabras clave como SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP y algunas otras.

Pero incluso sin la afluencia de palabras clave, «UNION BANK OF CALIFORNIA» contiene la palabra UNION. Y no es difícil pensar en frases que contengan la palabra OR.

Estrategia mixta

En última instancia, una buena solución WAF debe equilibrar varias estrategias para analizar caracteres especiales, palabras clave, tipos de parámetros y más.

Lamentablemente, incluso con todas las estrategias combinadas, es difícil lograr el equilibrio adecuado que permita la mayoría de las entradas legítimas y evite la mayoría de las maliciosas.

Automático o configurable

Uno de los desafíos que enfrentan las soluciones WAF se origina en las expectativas de los clientes. Quieren una solución de un solo clic. Con solo pulsar un botón, obtienen protección contra la inyección SQL. Como los clientes la desean, los vendedores prometen cumplirla.

Desafortunadamente, como hemos explicado hasta ahora, es simplemente imposible. Una solución que funcione en toda la aplicación y permita una entrada más legítima también resistirá al menos algunos tipos de ataques de inyección SQL. Basta con un solo tipo de ataque exitoso para comprometer todos los datos de la base de datos.

En lugar de buscar la solución «de un solo botón», los clientes que deseen personalizar diferentes estrategias para distintos tipos de entrada pueden disfrutar de una protección superior con menos falsos positivos.

Cuanta más configuración tenga la solución WAF y más granular sea el control, más probable será que se adapte a su aplicación específica y ofrezca una mejor protección.

Implementación

Al igual que con cualquier solución de software, existen diferencias significativas entre las implementaciones de WAF buenas y malas. Aquí hay algunos ejemplos que pueden parecer graciosos, pero que son totalmente reales:

  • WAF podría filtrar la palabra «union» en minúsculas, pero no filtrar «UNION» en mayúsculas ni «UnIoN» en mayúsculas y minúsculas.
  • WAF podría filtrar la palabra «OR», pero no detectó que %4F%52 es lo mismo en hexadecimal.

Los WAF presentan muchas otras posibles fallas y debilidades, y a la larga se convierten en un software más cuyos errores pueden explotarse.

Desafortunadamente, no existe una forma sencilla y fiable de medir la calidad de una solución WAF ni ninguna publicación imparcial. Probarla usted mismo con los numerosos ejemplos de esta página puede darle una idea de la calidad de una solución.

El desinfectante WAF

Algunas soluciones WAF bloquean la actividad maliciosa, otras la limpian y algunas ofrecen ambas opciones. El sanitizador es la parte del WAF que limpia la actividad maliciosa. Como cualquier software, este también puede tener debilidades.

Los sanitizadores tienen un tipo particular de debilidad que ocurre con frecuencia: al eliminar un ataque malicioso, exponen otro.

Si la solución WAF tiene la opción de bloquear la actividad potencialmente maliciosa y evitar el sanitizador, es más seguro hacerlo.

Por ejemplo, estas entradas:

1 O/**/R 1/**/=/**/1
un/**/ion SEselectLECT * F'RO'M

Se podría desinfectar eliminando comentarios, símbolos y palabras clave para producir:

1 OR 1=1
union SELECT * FROM

Firewall en la aplicación

Blue Core Research desarrolló un nuevo tipo de tecnología que puede complementar o reemplazar un WAF. Esta tecnología se ejecuta dentro de la aplicación en lugar de externamente y ofrece control sobre la protección aplicada a diferentes partes del código sin modificar el código fuente.

El Agente Java de Core Audit utiliza capacidades nativas de la JVM para añadir seguridad en tiempo de ejecución a los archivos JAR habituales que utiliza actualmente.

El Agente Java de Core Audit puede añadir varios tipos de seguridad, pero dado que este documento trata sobre la inyección SQL, solo detallaremos las capacidades de bloqueo básico que buscan abordar esta amenaza.

Los tipos de seguridad que puede agregar el agente Java de Core Audit son:

  • Auditoría (Niveles 2-3): Captura completa de las sesiones de la aplicación y su actividad. Los niveles 2-3 de auditoría nativa de aplicaciones de Core Audit incluyen generación de informes, alertas, análisis forense, análisis de perfiles de comportamiento y más.
  • Bloqueo básico: Aplique reglas de firewall tipo WAF en varios puntos de la aplicación. Más detalles a continuación.
  • Políticas de bloqueo (Niveles 4): Aplique reglas personalizadas sobre quién puede hacer qué en la aplicación. Por ejemplo, restrinja qué IP o usuarios pueden ejecutar qué actividad y en qué momento.
  • Bloqueo reactivo: Configure políticas que bloqueen automáticamente las IP o usuarios con demasiados inicios de sesión fallidos o errores en varios servidores de aplicaciones.

Control de filtros y parámetros

El Agente de Auditoría Central incluye múltiples filtros que se pueden aplicar según sea necesario a diferentes parámetros. Puede aplicar filtros de inyección SQL estrictos a algunos parámetros y más flexibles a otros.

Existen filtros numéricos para datos numéricos, filtros de cadena para datos textuales, filtros seguros generales que detectan automáticamente el tipo de dato, filtros de palabras clave y más. Disponer de múltiples filtros que se pueden aplicar de diferentes maneras le brinda la flexibilidad de adaptar el firewall en la aplicación a su aplicación.

Control de profundidad

Los filtros se pueden aplicar a cualquier método de la aplicación. Pueden aplicarse a parámetros de URL recibidos del usuario o a un método que crea una consulta SQL a partir de ellos.

Puede aplicar filtros flexibles a los parámetros de búsqueda que considere seguros y filtros estrictos al añadirlos a la consulta SQL para garantizar su seguridad.

Las áreas de la aplicación con código frágil pueden protegerse mejor, mientras que las partes del código probadas pueden tener mayor libertad para interactuar con el usuario.

Dado que los filtros se pueden aplicar a cualquier método dentro de la aplicación, no se limitan a filtrar la actividad web. Los filtros pueden aplicarse a datos leídos de archivos, de diversas fuentes de red, de bases de datos, actividad generada internamente, etc.

Control de contexto y acción

El firewall en la aplicación forma parte de la tecnología genérica de auditoría de aplicaciones de Core Audit. Por lo tanto, toda la información sobre posibles inyecciones SQL se vincula al contexto completo de la sesión del usuario.

Esto significa que toda actividad bloqueada se relacionará con la dirección IP, el usuario, el programa y cualquier otra información reportada por la aplicación. Podrá saber qué sucedió antes y después, incluso si esas acciones no activaron una alerta.

El firewall en la aplicación puede bloquear acciones lanzando excepciones. Estas excepciones se pueden personalizar para adaptarse al tipo de excepción que gestiona cada área del código.

Además, el firewall en la aplicación cuenta con un sanitizante de alta calidad que puede eliminar la amenaza identificada sin introducir otra.

Firewall en la aplicación o WAF

Una de las ventajas del WAF es que filtra la actividad antes de que llegue a la aplicación. El firewall en la aplicación no puede hacer esta afirmación.

Sin embargo, dado que el WAF siempre se ejecuta fuera de la aplicación, pierde el contexto en el que se ejecuta la actividad y la capacidad de aplicar diferentes filtros a diferentes niveles de la pila de aplicaciones.

El firewall en la aplicación ofrece un control granular sobre los tipos de filtros para que puedan satisfacer las necesidades específicas de cada parte de la aplicación. No es necesario sacrificar un filtro que, en general, funciona bien y no ofrece el nivel de protección adecuado.

El firewall en la aplicación se ejecuta dentro de la aplicación, por lo que no es necesario implementar máquinas adicionales ni filtrar el tráfico de red. Todo se ejecuta en la misma máquina y forma parte de la aplicación.

El firewall en la aplicación incluye auditoría completa de aplicaciones, proporcionada por Core Audit Niveles 2 y 3, y puede actualizarse para aplicar políticas de bloqueo basadas en contexto o reactivas con Core Audit Nivel 4. Todas estas funciones solo son posibles con la pila tecnológica de Core Audit.

Resumen

La inyección SQL es un ataque difícil de combatir, y reescribir la aplicación usando variables de enlace es la única solución real.

Si convertir la aplicación para que use solo variables de enlace no es viable, las tecnologías de auditoría central en la aplicación y la base de datos son las más eficaces para detectar y prevenir posibles ataques de inyección SQL.

Cada enfoque independiente tiene sus limitaciones, por lo que la mejor solución es un enfoque combinado que mejore el código, implemente una detección eficaz en la base de datos y medidas preventivas en la aplicación.

Más allá de la inyección SQL, las tecnologías de auditoría central pueden ayudar a proteger bases de datos y aplicaciones para garantizar que sus datos confidenciales no se vean comprometidos por actores externos o internos.