Cómo Usar AWS WAF Para Mejorar la Seguridad de tu Aplicación

Un tutorial paso a paso para desplegar AWS WAF para proteger tu aplicación de exploits comunes, sin modificar el código de la aplicación.

Published Apr 24, 2024
Has implementado la aplicación web más moderna, sofisticada e insegura: OWASP Juice Shop. Es una aplicación hecha intencionalmente insegura y contiene una gran cantidad de desafíos de hacking de dificultad variada donde se supone que el usuario debe explotar las vulnerabilidades subyacentes.
No vamos a hackearla, ¡vamos a asegurarla! (al menos parcialmente). Sin embargo, no tocaremos el código de la aplicación.
Utilizaremos los siguientes servicios de AWS:
  • CloudFront: Una Content Delivery Network (CDN) que almacena en caché el contenido en ubicaciones de borde distribuidas en todo el mundo y lo sirve a los usuarios con menos latencia que enviar una solicitud a tus servidores.
  • Web Application Firewall (WAF): Un firewall de aplicaciones web que te permite monitorear las solicitudes HTTP y HTTPS enviadas a tus recursos web y tomar acciones basadas en ciertos parámetros. Se integra con CloudFront.

Solución: Configurar Web Application Firewall (WAF) para bloquear solicitudes con exploits

Para seguir los pasos de este artículo, primero deberás implementar la configuración inicial. Aquí encontrarás el código, y puedes desplegarlo en AWS con el siguiente botón:

Paso 0: Probar la aplicación

Primero nos aseguraremos de que los exploits realmente funcionen. Si tu código ya te protege de estos, sigue siendo una buena idea agregar estas reglas de WAF, para que tengas otra capa de protección (¡defensa en profundidad!). Pero si los exploits no funcionaran en este tutorial, sería un tutorial realmente malo, ¿no?
  • En la consola de AWS, abre CloudShell
  • Establece la URL de tu distribución de CloudFront como una variable de entorno
  • Primero, ejecuta echo $JUICESHOP_URL para ver si ya está configurada. Si es así, eso es todo.
  • Si no está configurada, ve al stack inicial que implementaste en CloudFormation y, desde la pestaña Outputs, copia el valor de JuiceShopURL
  • Ejecuta JUICESHOP_URL=[el valor que acabas de copiar], reemplazando [el valor que acabas de copiar] con el valor que acabas de copiar, que se parece a algo como http://d1486tu9ui8f00.cloudfront.net
  • Ejecuta el siguiente comando, que envía una solicitud donde los argumentos de consulta contienen extensiones de archivos del sistema que no son seguras para leer o ejecutar: curl -I $JUICESHOP_URL?execute=http://evilhackerz.com/file.ini
  • Verifica que la respuesta sea 200 OK
  • Ejecuta el siguiente comando, que envía una solicitud con un ataque de Cross-Site Scripting: curl -X POST $JUICESHOP_URL -F "user=''"
  • Verifica que la respuesta sea 200 OK (debería ser un HTML con <title>OWASP Juice Shop</title>)
  • Ejecuta el siguiente comando, que intenta una inyección SQL: curl -X POST $JUICESHOP_URL -F "user='AND 1=1;"
  • Verifica que la respuesta sea 200 OK (debería ser un HTML con <title>OWASP Juice Shop</title>)
  • Ejecuta el siguiente comando, que intenta una inyección SQL más compleja: curl -X POST $JUICESHOP_URL -F "1094 and 3=substirng(version(),1,1)"
  • Verifica que la respuesta sea 200 OK (debería ser un HTML con <title>OWASP Juice Shop</title>)

Paso 1: Crear una Web ACL de WAF

Una Web ACL no protege nada por sí sola. Es el motor que ejecuta todo lo que hace WAF y es el recurso principal de WAF. En este paso, solo la estamos creando y, en los próximos pasos, agregaremos las protecciones reales: las reglas.
  • Ve a la Consola de AWS WAF
  • Haz clic en Create web ACL
  • Para el nombre y la descripción, ingresa simple-aws-waf
  • Establece el tipo de recurso como Amazon CloudFront distributions
  • En Associated AWS resources, haz clic en Add AWS resources
  • Elige la distribución de CloudFront que se creó con la configuración inicial y haz clic en Add
  • Haz clic en Next
  • Haz clic en Next
  • En la página Configure metrics, en Request sampling options, selecciona Enable sampled requests
  • Haz clic en Next
  • Haz clic en create web ACL

Paso 2: Habilitar el registro de WAF

Si un árbol cae en un bosque y no hay nadie cerca para escucharlo, ¿hace ruido? En realidad sí, debido a la conservación de la energía. Pero en este caso, queremos saber qué está haciendo WAF, para eso son los registros.
  • Haz clic en la web ACL que acabas de crear y abre la pestaña Logging and metrics
  • En la sección Logging, haz clic en Enable
  • Para Logging destination, asegúrate de que esté seleccionado CloudWatch Logs log group
  • Para el grupo de registro, haz clic en Create new
  • Para el nombre del grupo de registro, ingresa aws-waf-logs-simple-aws-waf
  • Deja las otras configuraciones en sus valores predeterminados y haz clic en Create
  • Vuelve a la pestaña del navegador con la consola de WAF, actualiza la lista de grupos de registro y selecciona el grupo de registro que acabas de crear
  • Haz clic en Save
  • En la sección Sampled requests, haz clic en Edit
  • Selecciona Enable sampled requests
  • Haz clic en Save

Paso 3: Agregar grupos de reglas administradas por AWS a la web ACL

¡Aquí es donde realmente protegemos nuestra aplicación! Los grupos de reglas son conjuntos de reglas que WAF evaluará para cada solicitud. Las reglas tienen declaraciones como "Si la solicitud contiene el encabezado X" y acciones que pueden ser Allow, Block, Count o CAPTCHA y Challenge. Las solicitudes se evalúan con todas las declaraciones de reglas para ver si coinciden, y si hay una coincidencia, se aplica la acción de la regla. Las reglas se agrupan en grupos de reglas para facilitar su gestión.
Los grupos de reglas administradas son grupos de reglas ya creados por AWS, con reglas que te protegerán de algunos exploits comunes como Cross-Site Scripting (XSS). En este paso, habilitaremos un par de ellos, que nos protegerán de los primeros 2 exploits.
  • Ve a la consola de WAF y selecciona tu web ACL
  • Haz clic en la pestaña Rules
  • En la sección Rules, haz clic en Add rules y luego haz clic en Add managed rule groups
  • Expande la lista de los grupos de reglas administradas por AWS
  • En la columna Action, activa el botón Add to web ACL para Core Rule Set y SQL Database
  • Haz clic en Add rules y luego haz clic en Save

Paso 4: ¡Probar las reglas!

Tenemos nuestras reglas en su lugar, ¡ahora es el momento de probarlas! Volvamos a ejecutar los dos primeros exploits y veamos si las solicitudes son bloqueadas por WAF.
  • En la consola de AWS, abre CloudShell
  • Establece la URL de tu distribución de CloudFront como una variable de entorno
  • Primero, ejecuta echo $JUICESHOP_URL para ver si ya está configurada. Si es así, ve al siguiente paso.
    • Si no está configurada, ve al stack inicial que implementaste en CloudFormation y, desde la pestaña Outputs, copia el valor de JuiceShopURL
  • Ejecuta JUICESHOP_URL=[el valor que acabas de copiar], reemplazando [el valor que acabas de copiar] con el valor que acabas de copiar, que se parece a algo como http://d1486tu9ui8f00.cloudfront.net
  • Ejecuta el siguiente comando, que envía una solicitud donde los argumentos de consulta contienen extensiones de archivos del sistema que no son seguras para leer o ejecutar: curl -I $JUICESHOP_URL?execute=http://evilhackerz.com/file.ini
  • Verifica que la respuesta sea 403 Forbidden
  • Ejecuta el siguiente comando, que envía una solicitud con un ataque de Cross-Site Scripting: curl -X POST $JUICESHOP_URL -F "user=''"
  • Verifica que la respuesta sea 403 Forbidden (debería ser un HTML con <title>ERROR: The request could not be satisfied</title>)

Paso 5: Agregar una regla para bloquear inyecciones SQL

En este paso, agregaremos una regla personalizada que nos protegerá de las inyecciones SQL. En realidad, no estamos escribiendo la declaración, sino usando una coincidencia ya predefinida por AWS: Contains SQL injection attacks. Sin embargo, estamos eligiendo todas las demás opciones.
  • Ve a la consola de WAF y selecciona tu web ACL
  • Haz clic en la pestaña Rules
  • En la sección Rules, haz clic en Add rules y haz clic en Add my own rules and rule groups
  • Para el nombre de la regla, ingresa block-sql-injection
  • En el desplegable If a request, asegúrate de que esté seleccionado matches the statement
  • En Statement:
    • Para Inspect, selecciona Body
    • Para Match type, selecciona Contains SQL injection attacks (es un campo de búsqueda)
    • Para Oversize handling, selecciona Continue
    • Para Sensitivity level, selecciona High
  • Haz clic en Add Rule
  • Haz clic en Save

Paso 6: Probar la regla de inyección SQL

Con la nueva regla en su lugar, volvemos a ejecutar los dos últimos exploits, que eran inyecciones SQL de diferente complejidad. Ambos deberían ser bloqueados.
  • En la consola de AWS, abre CloudShell
  • Establece la URL de tu distribución de CloudFront como una variable de entorno
  • Primero, ejecuta echo $JUICESHOP_URL para ver si ya está configurada. Si es así, ve al siguiente paso.
    • Si no está configurada, ve a la pila inicial que implementaste en CloudFormation y, desde la pestaña Outputs, copia el valor de JuiceShopURL
  • Ejecuta JUICESHOP_URL=[el valor que acabas de copiar], reemplazando [el valor que acabas de copiar] con el valor que acabas de copiar, que se parece a algo como http://d1486tu9ui8f00.cloudfront.net
  • Ejecuta el siguiente comando, que intenta una inyección SQL: curl -X POST $JUICESHOP_URL -F "user='AND 1=1;"
  • Verifica que la respuesta sea 403 ERROR (debería ser un HTML con <title>ERROR: The request could not be satisfied</title>)
  • Ejecuta el siguiente comando, que intenta una inyección SQL más compleja: curl -X POST $JUICESHOP_URL -F "1094 and 3=substirng(version(),1,1)"
  • Verifica que la respuesta sea 403 ERROR (debería ser un HTML con <title>ERROR: The request could not be satisfied</title>)
En el paso anterior, te dije que seleccionaras High para Sensitivity level. Si hubieras seleccionado Low, el primero de estos dos exploits (una inyección SQL realmente simple) habría sido bloqueado, pero el último (una inyección SQL más compleja) no habría sido detectado. Sin embargo, un nivel de sensibilidad High también puede causar falsos positivos, así que pruébalo tú mismo.

Paso 7: Ver los registros de WAF en CloudWatch Logs

Ya hemos visto WAF en acción desde el punto de vista del atacante. Pero en un escenario real, probablemente no serás tú quien ataque. Desde tu punto de vista, la información que tienes son los registros.
  • Ve a la consola de WAF y selecciona tu web ACL
  • Haz clic en la pestaña CloudWatch Logs Insights
  • Haz clic en Run query
  • En la pestaña Logs que apareció debajo, abre las entradas de registro y tómate unos segundos para leerlas
  • Considera brevemente lo doloroso que sería leer estos registros
  • En el área de texto sobre el botón Run query, borra todo y pega lo siguiente:fields httpRequest.clientIp as ClientIP, httpRequest.country as Country, httpRequest.uri as URI, terminatingRuleId as Rule| filter action = "BLOCK"| stats count(*) as RequestCount by Country, ClientIP, URI, Rule| sort RequestCount desc
  • Haz clic en Run query nuevamente
  • Ahora revisa los registros. Mucho mejor, ¿verdad?
Bonus: ¡Puedes hacer consultas agregadas! Aquí tienes una lista de consultas útiles que puedes copiar.

Costo de AWS WAF

Los precios de WAF son bastante complejos y encontrarás 9 ejemplos diferentes en la página de precios. Sin embargo, aquí están los conceptos básicos:
  • Como base, se te cobra $5/mes por Web ACL
  • Más $1/mes por grupo de reglas (administrado o creado por ti)
  • Más $1/mes por regla personalizada (ya sea en un grupo de reglas o no)
  • Más $0.60 por cada 1 millón de solicitudes (hasta 16KB de cuerpo, hasta 1500 WCU)
  • Más $0.30 por millón de solicitudes por cada 16KB adicionales
  • Más $0.20 por millón de solicitudes por cada 500 WCU adicionales
Las WCU son Web ACL Capacity Units (Unidades de Capacidad de Web ACL). Cuando creas una regla, WAF calcula cuántas WCU consume dependiendo de la complejidad de la regla. Para los grupos de reglas, cuando los creas, estableces la capacidad de WCU (no se puede cambiar más tarde), y luego la suma de las WCU de todas las reglas que agregas no puede exceder la capacidad de WCU de ese grupo de reglas. Cuando asignas reglas y grupos de reglas a una Web ACL, las WCU consumidas por la Web ACL son la suma de las WCU de todas las reglas asociadas directamente, más la suma de la capacidad de WCU de todos los grupos de reglas asociados con la Web ACL.
Como referencia, las 1500 WCU incluidas en el precio base de $5/mes generalmente son muchas. La cantidad máxima de WCU que puede tener una Web ACL es 5000 (se puede aumentar contactando al soporte)
Con respecto al cuerpo, puedes decidir qué hacen las reglas cuando el cuerpo excede los 16 KB. Eso es el Continue que estableciste para Oversize handling en el Paso 5.
Escribí un artículo más detallado sobre los precios de WAF, que tal vez quieras consultar (está en inglés).
Por cierto, ¡puedes comprar grupos de reglas de WAF en AWS Marketplace!

Mejores prácticas para AWS WAF

Excelencia operativa

  • Implementar monitoreo y alertas continuas: Configura alarmas de CloudWatch para monitorear las métricas de WAF, como la cantidad de solicitudes bloqueadas y coincidencias de reglas. Configura notificaciones automatizadas para recibir alertas cuando se detecten posibles amenazas de seguridad. Esto te ayuda a responder proactivamente y mitigar los riesgos de seguridad.
  • Habilitar los logs de WAF: Ya hicimos esto =). También analizamos los registros con CloudWatch Logs Insights, pero también puedes usar Athena o Elasticsearch para comprender mejor los posibles patrones de ataque y ajustar las reglas de WAF en consecuencia.

Seguridad

  • Actualizar regularmente las reglas de WAF: La seguridad es una carrera para corregir los últimos exploits. Mantente al día con las últimas amenazas y actualiza tus reglas de WAF. Los grupos de reglas administradas se actualizan automáticamente, pero si eres un profesional de seguridad, probablemente quieras estar al tanto de esto.
  • Utiliza IAM para crear permisos de mínimo privilegio: Como siempre, utiliza mínimo privilegio cuando definas permisos. En especial para tus instancias, ya que si WAF no captura algún ataque, podrían acceder a la instancia EC2 y desde allí ganar más accesos.

Fiabilidad

  • Probar y validar las reglas de WAF: ¡De los 7 pasos que tuvimos en nuestro tutorial paso a paso, 3 fueron de prueba! Configura las reglas, luego pruébalas, luego pruébalas periódicamente, luego infórmate sobre nuevas amenazas y ¡pruébalas de nuevo!

Eficiencia del rendimiento

Esta vez no tengo nada que decir aquí.

Optimización de costos

  • Usar grupos de reglas administradas: Se te cobra $1/mes por regla personalizada y solo $1/mes por un grupo completo de reglas administradas. ¡Resuelve lo que puedas con grupos de reglas administradas! Sin embargo, mantén un ojo en las WCU.

Recursos de AWS WAF

El paper Lineamientos para Implementar AWS WAF (en inglés) de AWS describe recomendaciones para implementar AWS WAF para proteger aplicaciones web existentes y nuevas. ¡Una gran lectura antes de arruinar la seguridad de tu aplicación! Y probablemente una gran lectura si ya la has arruinado.
 

Comments