Crea y visualiza reglas de políticas de seguridad de Cloud Armor

Cada regla de política de seguridad de Google Cloud Armor tiene una prioridad, una condición de coincidencia y una acción. Cloud Armor realiza la acción de la regla de prioridad más alta que coincide con una solicitud. Las reglas con una prioridad más baja que la regla de coincidencia de prioridad más alta no se evalúan, incluso si tienen las mismas condiciones de coincidencia.

Cada regla de política de seguridad admite dos tipos de condiciones de coincidencia:

  • Una condición de coincidencia básica contiene listas de direcciones IP o listas de rangos de direcciones IP. Las condiciones de coincidencia básicas se definen con la marca --src-ip-ranges cuando se crea una regla con Google Cloud CLI.
  • Una condición de coincidencia avanzada contiene una expresión con hasta cinco subexpresiones que pueden coincidir con una variedad de atributos de una solicitud entrante. Las condiciones de coincidencia avanzadas se definen con la marca --expression cuando se crea una regla con Google Cloud CLI.

En esta página, se describe cómo crear y ver reglas de políticas de seguridad, y se proporciona la referencia para el lenguaje de reglas personalizadas de Cloud Armor que usas para escribir expresiones en condiciones de coincidencia avanzadas. El lenguaje de reglas personalizadas de Cloud Armor es un subconjunto del lenguaje de expresión común (CEL).

Las expresiones escritas en el lenguaje de reglas personalizadas de Cloud Armor requieren dos componentes:

  • El atributo: los datos que se inspeccionarán
  • La operación: cómo usar los datos

Por ejemplo, en la siguiente expresión, se usan los atributos origin.ip y 198.51.100.0/24 en la operación inIpRange. En este caso, la expresión devuelve true si origin.ip está dentro del rango de direcciones IP 198.51.100.0/24.

inIpRange(origin.ip, '198.51.100.0/24')

Aunque la expresión del ejemplo anterior solo coincide con la dirección IP del cliente, cuando usas la expresión de ejemplo en una regla de política de seguridad de Cloud Armor, la regla se considera una regla con condiciones de coincidencia avanzadas desde una perspectiva de cuota. Para obtener más información, consulta Cuotas y límites de Cloud Armor.

Crea reglas de política de seguridad

Sigue los pasos de esta sección para agregar reglas a una política de seguridad de Cloud Armor.

Console

  1. En la consola de Google Cloud , ve a la página Políticas de Cloud Armor.

    Ir a Políticas de Cloud Armor

  2. Haz clic en el nombre de la política de seguridad para abrir la página Detalles de la política y, luego, haz clic en la pestaña Reglas.

  3. Haz clic en Agregar regla.

  4. Ingresa una descripción de la regla (opcional).

  5. Selecciona el modo:

    • Modo básico: Permite o rechaza el tráfico en función de las direcciones IP o los rangos de IP.
    • Modo avanzado: Permite o rechaza el tráfico según las expresiones de las reglas.
  6. En el campo Coincidencia, especifica las condiciones a las que se aplica la regla:

    • Modo básico: Ingresa de 1 a 10 rangos de direcciones IP para que coincidan con la regla. Puedes agregar un máximo de 10 rangos de direcciones IP. Para conocer los límites, consulta Cuotas y límites de Cloud Armor.

    • Modo avanzado:

      • Creador de condiciones de coincidencia (versión preliminar): Usa el creador visual para crear expresiones sin escribir código CEL sin procesar. Combina y agrupa condiciones, y aplica transformaciones de cadenas. Consulta Cómo usar el creador de condiciones de coincidencia.
      • Editor de condiciones de coincidencia: ingresa una expresión para evaluar en función de las solicitudes entrantes. Para obtener más información, consulta Operaciones y Atributos.
  7. En la lista Acción, selecciona Permitir o Rechazar.

  8. Si configuras una regla de rechazo, selecciona un código de respuesta en la lista Código de respuesta.

  9. Para habilitar el modo de vista previa de la regla, selecciona Habilitar.

  10. En el campo Prioridad, ingresa un número entero del 0 al 2,147,483,646. Cloud Armor evalúa las reglas en orden de prioridad de 0 (la más alta) a 2,147,483,647 (la más baja). La regla predeterminada tiene una prioridad de 2,147,483,647.

  11. Haz clic en Agregar.

gcloud

Usa el comando gcloud compute security-policies rules create PRIORITY. Reemplaza PRIORITY por la prioridad de la regla en la política:

gcloud compute security-policies rules create PRIORITY \
    --security-policy POLICY_NAME \
    --description DESCRIPTION \
    --src-ip-ranges IP_RANGES | --expression EXPRESSION \
    --action=[ allow | deny-403 | deny-404 | deny-502 ] \
    --preview

Por ejemplo, con el siguiente comando, se agrega una regla con una prioridad de 1,000 para bloquear el tráfico de los rangos de direcciones IP 192.0.2.0/24 y 198.51.100.0/24:

gcloud compute security-policies rules create 1000 \
    --security-policy my-policy \
    --description "block traffic from 192.0.2.0/24 and 198.51.100.0/24" \
    --src-ip-ranges "192.0.2.0/24","198.51.100.0/24" \
    --action "deny-403"

Usa la marca --expression para especificar una condición. Con el siguiente comando, se agrega una regla para permitir el tráfico desde la dirección IP 1.2.3.4 que contiene la cadena example en el encabezado User-Agent:

gcloud compute security-policies rules create 1000 \
    --security-policy my-policy \
    --expression "inIpRange(origin.ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('example')" \
    --action allow \
    --description "Block User-Agent 'example'"

Con el siguiente comando, se agrega una regla para bloquear las solicitudes si la cookie de la solicitud contiene un valor específico:

gcloud compute security-policies rules create 1000 \
    --security-policy my-policy \
    --expression "has(request.headers['cookie']) && request.headers['cookie'].contains('80=SomeValue')" \
    --action deny-403 \
    --description "Cookie Block"

Con el siguiente comando, se agrega una regla para bloquear solicitudes de la región AU:

gcloud compute security-policies rules create 1000 \
    --security-policy my-policy \
    --expression "origin.region_code == 'AU'" \
    --action deny-403 \
    --description "AU block"

Con el siguiente comando, se agrega una regla para bloquear las solicitudes de la región AU que no están en el rango de IP especificado:

gcloud compute security-policies rules create 1000 \
    --security-policy my-policy \
    --expression "origin.region_code == \"AU\" && !inIpRange(origin.ip, '1.2.3.0/24')" \
    --action deny-403 \
    --description "country and IP block"

Con el siguiente comando, se agrega una regla para bloquear las solicitudes con un URI que coincida con una expresión regular:

gcloud compute security-policies rules create 1000 \
    --security-policy my-policy \
    --expression "request.path.matches('/example_path/')" \
    --action deny-502 \
    --description "regex block"

Con el siguiente comando, se agrega una regla para bloquear las solicitudes si el valor decodificado en Base64 del encabezado user-id contiene un valor específico:

gcloud compute security-policies rules create 1000 \
    --security-policy my-policy \
    --expression "has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')" \
    --action deny-403 \
    --description "country and IP block"

Con el siguiente comando, se agrega una regla que usa un conjunto de expresiones preconfiguradas del conjunto de reglas principales (CRS) 4.22 de OWASP para mitigar los ataques de inyección de SQL (SQLi):

gcloud compute security-policies rules create 1000 \
    --security-policy my-policy \
    --expression "evaluatePreconfiguredWaf('sqli-v422-stable')" \
    --action deny-403

Usa el creador de condiciones de coincidencia

El compilador de condiciones de coincidencia es una interfaz visual en la consola de Google Cloud que te ayuda a crear expresiones de reglas de Cloud Armor complejas sin escribir código de Common Expression Language (CEL). En lugar de escribir código, puedes usar la IU estructurada del compilador para combinar condiciones y lógica de grupo, lo que puede ayudarte a evitar errores de sintaxis y visualizar mejor la estructura de la regla. El compilador admite listas planas y lógica anidada de hasta cinco niveles de expresiones. Usa esta herramienta cuando configures reglas para ayudar a proteger backends de múltiples nubes o implementaciones híbridas, en las que es posible que debas inspeccionar atributos de solicitud específicos antes de enrutar el tráfico.

Funciones del creador de condiciones de coincidencia

El creador de condiciones de coincidencia incluye las siguientes funciones:

  • Lógica y anidamiento: Combina varias condiciones con los operadores AND y OR. El compilador admite la agrupación y el anidamiento de hasta cinco expresiones.
  • Transformaciones de cadenas: Para los atributos basados en cadenas (como request.path o request.headers), aplica transformaciones para normalizar los datos antes de la evaluación. Entre las transformaciones compatibles, se incluyen las siguientes:
    • Minúsculas y mayúsculas
    • Decodifica en Base64
    • Decodificación de URL y decodificación de URL (Unicode)
    • Convertir de UTF-8 a Unicode
  • Análisis bidireccional: Cambia entre el creador de condiciones de coincidencia visual y el editor de condiciones de coincidencia de texto sin formato. La IU analiza automáticamente el código CEL sin procesar y lo convierte en bloques visuales.
  • Compatibilidad con funciones: El compilador proporciona controles de la IU para expresiones basadas en funciones, como reglas de WAF preconfiguradas, grupos de direcciones y inteligencia contra amenazas.

Limitaciones

El creador de condiciones de coincidencia es la interfaz predeterminada para la creación de reglas avanzadas. Si una expresión contiene lógica no admitida (como macros desconocidas), el compilador se inhabilita. En estos casos, usa el texto sin procesar en el editor de condiciones de coincidencia para editar la regla.

Además, la disponibilidad de ciertas expresiones en el compilador depende del nivel de Google Cloud Armor Enterprise de tu proyecto y del tipo de política de seguridad.

Expresiones de muestra

Las siguientes son expresiones de ejemplo. Para obtener más información sobre las operaciones y los atributos compatibles, consulta Operaciones y Atributos.

Si tu regla o expresión usa códigos de país o región ISO 3166-1 alfa-2, Cloud Armor trata cada código de forma independiente. Las reglas y expresiones de Cloud Armor usan esos códigos para permitir o rechazar solicitudes.

  • La siguiente expresión coincide con las solicitudes de la dirección IP 1.2.3.4 que contienen la cadena example en el encabezado User-Agent:

    inIpRange(origin.ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('example')
    

    Como alternativa, haz coincidir el rango de direcciones IP de un encabezado de dirección IP de cliente personalizado con el atributo origin.user_ip:

    inIpRange(origin.user_ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('example')
    
  • La siguiente expresión coincide con las solicitudes que tienen una cookie con un valor específico:

    has(request.headers['cookie']) && request.headers['cookie'].contains('cookie_name=cookie_value')
    
  • La siguiente expresión coincide con las solicitudes de la región AU:

    origin.region_code == 'AU'
    
  • La siguiente expresión coincide con las solicitudes de la región AU que no están en el rango de IP especificado:

    origin.region_code == "AU" && !inIpRange(origin.ip, '1.2.3.0/24')
    
  • La siguiente expresión coincide con las solicitudes con una ruta de acceso de variable numerada a un archivo específico si el URI coincide con una expresión regular:

    request.path.matches('/path/[0-9]+/target_file.html')
    
  • La siguiente expresión coincide con las solicitudes si el valor decodificado en Base64 del encabezado de user-id contiene un valor específico:

    has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')
    
  • En la siguiente expresión, se usa un conjunto de expresiones preconfiguradas del conjunto de reglas de OWASP CRS 4.22 para establecer coincidencias con ataques de SQLi:

    evaluatePreconfiguredWaf('sqli-v422-stable')
    

Salto de directorio y normalización

Normaliza el contenido en tus reglas basadas en rutas para administrar las reglas de codificación y de recorrido de rutas, y para crear reglas generalizadas que eviten el uso de mayúsculas o la codificación específica del contenido.

Cuando escribas reglas que usen startsWith, endsWith o contains para que coincidan con request.path, usa lower y urlDecode para normalizar la ruta de acceso antes de la coincidencia. Esto ayuda a evitar omisiones que usan codificación de URL o variaciones de mayúsculas y minúsculas.

Por ejemplo, para bloquear el acceso al directorio /admin, usa la siguiente expresión:

request.path.lower().urlDecode().startsWith('/admin')

Esta regla bloquea las solicitudes de /admin, /Admin, /a%64min y otras variaciones.

Cuando escribas reglas que usen matches para que coincidan con request.path, ten en cuenta el carácter de barra inversa (\) en tu expresión regular.

Por ejemplo, para bloquear el acceso al directorio /admin, usa la siguiente expresión para bloquear las omisiones que usan el carácter de barra inversa (\):

request.path.matches(r'^/\\*admin')

Combina esto con urlDecode para controlar la codificación de URL y las omisiones del carácter de barra inversa (\):

request.path.urlDecode().matches(r'^/\\*admin')

Visualiza las reglas de la política de seguridad

En las siguientes secciones, se describe cómo puedes enumerar las reglas configuradas en una política de seguridad y ver las reglas de WAF preconfiguradas disponibles.

Enumera las reglas en una política de seguridad

Sigue los pasos de esta sección para generar una lista de las reglas en una política de seguridad de Cloud Armor.

Console

  1. En la consola de Google Cloud , ve a la página Políticas de Cloud Armor.

    Ir a Políticas de Cloud Armor

  2. Haz clic en el nombre de la política de seguridad específica. En la página Detalles de la política, se muestran las reglas de la política en la pestaña Reglas.

gcloud

Usa el siguiente comando de gcloud para enumerar todas las reglas de una política de seguridad:

gcloud compute security-policies describe NAME

Usa el siguiente comando de gcloud para enumerar todas las reglas de una sola política de seguridad en una región especificada junto con una descripción de la política:

gcloud compute security-policies describe NAME \
  --region REGION

Usa el siguiente comando de gcloud para describir una regla:

gcloud compute security-policies rules describe PRIORITY \
    --security-policy POLICY_NAME

Por ejemplo, con el siguiente comando, se describe la regla con una prioridad de 1000 en la política de seguridad my-policy:

gcloud compute security-policies rules describe 1000 \
    --security-policy my-policy

Resultado:

action: deny(403)
description: block traffic from 192.0.2.0/24 and 198.51.100.0/24
kind: compute#securityPolicyRule
match:
  srcIpRanges:
  - '192.0.2.0/24'
  - '198.51.100.0/24'
preview: false
priority: 1000

Para obtener más información, consulta gcloud compute security-policies describe.

Enumera las reglas preconfiguradas disponibles

Además de las reglas que configuras, Cloud Armor proporciona reglas preconfiguradas que puedes usar en tus políticas de seguridad. Puedes enumerar las reglas preconfiguradas para ver las reglas y firmas predefinidas de protección de aplicaciones, como el conjunto de reglas principales de OWASP (CRS), que proporciona Cloud Armor. Estas reglas contienen firmas integradas que Cloud Armor evalúa en función de las solicitudes entrantes. Agrega estas reglas preconfiguradas a las reglas nuevas o existentes con el lenguaje de reglas personalizadas. Te recomendamos que uses la versión más reciente de la regla de CRS siempre que sea posible.

gcloud

  1. Ejecuta el comando gcloud compute security-policies list-preconfigured-expression-sets:

    gcloud compute security-policies list-preconfigured-expression-sets
    

    En el siguiente ejemplo, se muestra el formato del resultado del comando:

    EXPRESSION_SET
    expression-set-1
       RULE_ID                SENSITIVITY
       expression-set-1-id-1  sensitivity-value-1
       expression-set-1-id-2  sensitivity-value-2
    expression-set-2
       alias-1
       RULE_ID                SENSITIVITY
       expression-set-2-id-1  sensitivity-value-1
       expression-set-2-id-2  sensitivity-value-2
    

    En el siguiente ejemplo, se incluye una muestra del resultado real del comando. Ten en cuenta que, en el resultado real, se incluyen todas las reglas que se enumeran en Ajusta las reglas de WAF de Cloud Armor.

    gcloud compute security-policies list-preconfigured-expression-sets
    
    EXPRESSION_SET
    sqli-canary
        RULE_ID                          SENSITIVITY
        owasp-crs-v042200-id942120-sqli  2
        …
    xss-canary
        RULE_ID                         SENSITIVITY
        owasp-crs-v042200-id941110-xss  1
        owasp-crs-v042200-id941120-xss  2
    …
    sourceiplist-fastly
    sourceiplist-cloudflare
    sourceiplist-imperva
    

Operaciones

En la siguiente referencia, se describen los operadores que puedes usar con atributos (representados por x, y y k) para definir expresiones de reglas.

Operaciones Expresiones Descripción
Igualdad x == y Devuelve true si x es igual a y.
Igualdad, literal de cadena x == "foo" Devuelve true si x es igual al literal de cadena constante dado.
Igualdad, literal de cadena sin procesar x == R"fo'o" Devuelve true si x es igual al literal de cadena sin procesar dado que no interpreta secuencias de escape. Los literales de string sin procesar son convenientes para expresar strings que deben usar caracteres de secuencia de escape.
NOT lógico !x Devuelve true si el valor booleano x es false, o devuelve false si el valor booleano x es true.
Desigualdad x != y Devuelve true si x no es igual a y.
Concatenación x + y El resultado es la string concatenada xy.
AND lógico x && y Devuelve true si x e y son true.
OR lógico x || y Devuelve true si x, y o ambos son true.
Contiene una substring x.contains(y) Devuelve true si la cadena x contiene la subcadena y.
Comienza con una substring x.startsWith(y) Devuelve true si la cadena x comienza con la subcadena y.
Termina con una cadena secundaria x.endsWith(y) Devuelve true si la cadena x termina con la subcadena y.
Concordancia de expresión regular x.matches(y) Devuelve true si la cadena x coincide parcialmente con el patrón RE2 y especificado. El patrón RE2 se compila con la opción RE2::Latin1, que inhabilita las funciones de Unicode.
Dirección IP dentro del rango inIpRange(x, y) Devuelve true si la dirección IP x está contenida en el rango de IP y.
Minúscula x.lower() Muestra el valor de la string x en minúsculas.
Uppercase x.upper() Muestra el valor de la string x en mayúsculas.
Valor decodificado en Base64 x.base64Decode() Devuelve el valor decodificado en Base64 de x. El guion bajo (_) y el guion (-) se reemplazan primero por la barra diagonal (/) y el signo más (+), respectivamente. Devuelve "" (cadena vacía) si x no es un valor de Base64 válido.
Valor del mapa de claves m['k'] Devuelve el valor de la clave k en el mapa de cadena a cadena m si k está disponible; de lo contrario, devuelve un error. El enfoque recomendado es verificar primero la disponibilidad con "has(m['k'])==true".
Cómo verificar la disponibilidad de claves en un mapa has(m['k']) Devuelve true si la clave k está disponible en el mapa m.
Convertir en número entero int(x) Convierte el resultado de la string de x en un tipo de int. Luego, se puede usar con el fin de hacer una comparación de números enteros mediante operadores aritméticos estándar como > y <=. Esto funciona solo para valores que deben ser enteros.
Longitud size(x) Devuelve la longitud de la cadena x.
Decodificar URL x.urlDecode() Devuelve el valor decodificado en URL de x; las secuencias de caracteres en formato %## se reemplazan por los equivalentes que no son ASCII y + se reemplaza por un espacio. Las codificaciones no válidas se devuelven tal como están.
Decodificar URL (Unicode) x.urlDecodeUni() Devuelve el valor decodificado en URL de x; además de urlDecode(), esto también controla secuencias de caracteres Unicode en formato %u###. Las codificaciones no válidas se devuelven tal como están.
Convertir de UTF-8 a Unicode x.utf8ToUnicode() Devuelve la representación Unicode en minúsculas de un x codificado en UTF-8.
Ya existe. m.exists(k, expr) Devuelve true si al menos una entrada en el mapa m cumple con expr, en el que k representa la clave de cada entrada del mapa.
Existe uno m.exists_one(k, expr) Devuelve true si exactamente una entrada en el mapa m cumple con expr, en el que k representa la clave de cada entrada del mapa.
Todos m.all(k, expr) Devuelve true si todas las entradas del mapa m cumplen con expr, donde k representa la clave de cada entrada del mapa.
Filtro m.filter(k, expr) Devuelve un mapa que contiene solo las entradas del mapa m en el que la entrada satisface expr, donde k representa la clave de cada entrada del mapa.
Mapa m.map(k, expr) Devuelve una lista que contiene el resultado de evaluar expr para cada clave en el mapa m, donde k representa la clave de cada entrada del mapa.

Atributos

Los atributos representan información de una solicitud entrante, como la dirección IP del cliente o la ruta de URL solicitada.

Campo Tipo Descripción del campo
origin.ip cadena Es la dirección IP del cliente que inició la solicitud.
origin.user_ip cadena Es la dirección IP del cliente de origen, que un proxy upstream incluye en HTTP-HEADER. Antes de usar este atributo, debes configurar la opción userIpRequestHeaders[] en el campo advancedOptionsConfig de la política de seguridad para que coincida con un origen como True-Client-IP, X-Forwarded-For o X-Real-IP. Para obtener más información, consulta Descripción general de las direcciones IP de los usuarios.

Si no configuras la opción userIpRequestHeaders[], si el encabezado configurado contiene valores de dirección IP no válidos o si el encabezado configurado no está presente, origin.user_ip se establece de forma predeterminada en origin.ip. Para obtener más información, consulta la referencia del recurso securityPolicy.

origin.tls_ja4_fingerprint cadena Huella digital de TLS/SSL de JA4 si el cliente se conecta con HTTPS, HTTP/2 o HTTP/3. Si no está disponible, se devuelve una cadena vacía.
origin.tls_ja3_fingerprint cadena Huella digital de TLS/SSL de JA3 si el cliente se conecta con HTTPS, HTTP/2 o HTTP/3. Si no está disponible, se devuelve una cadena vacía.
request.headers mapa Es un mapa de cadena a cadena de los encabezados de la solicitud HTTP. Si un encabezado tiene varios valores, el valor correspondiente en este mapa es una sola cadena que contiene todos los valores, separados por comas. Las claves en este mapa están en minúsculas. Los balanceadores de cargas de aplicaciones externos inspeccionan todos los encabezados aceptados y se aplican las mismas limitaciones.

Usa has() para verificar la disponibilidad, como has(request.headers['header-key']) && request.headers['header-key'] != 'header-value'.

Puedes iterar sobre el mapa para verificar las claves y los valores. Sin embargo, solo puedes usar operadores de iteración de mapas (exists(), exists_one(), all(), filter() y map()) en request.headers en combinación con request.body o request.params en la misma expresión, por ejemplo, request.body && request.headers.exists(k, k.lower().startsWith('header-prefix')).

request.body cadena Representa el cuerpo de la solicitud como una cadena sin procesar. Puede representar datos de cualquier Content-Type. Almacena el contenido como una cadena sin ningún análisis automático.
request.params mapa Es un mapa de pares clave-valor que se agregan a la URL o se incluyen en el cuerpo de las solicitudes.
Solicitud de URI: name1=value1&name2=value2
Cuerpo de la solicitud JSON con Content-Type: application/json:
{ "username": "johndoe", "email": "johndoe@example.com" }
Cuerpo de la solicitud POST de GraphQL con Content-Type: application/graphql:
{ Username: "exampleUser", query: "/* other fields */" }
Cuerpo de la solicitud POST del formulario con Content-Type: application/x-www-form-urlencoded:
"username=exampleUser&email=johndoe%40example.com"
request.method cadena Es el método de solicitud HTTP.
request.path cadena La ruta de URL HTTP solicitada. Cuando escribas reglas que coincidan con request.path, te recomendamos que normalices la ruta para facilitar la sintaxis de coincidencia en caso de codificación de URL, variaciones de mayúsculas y minúsculas, o barras inversas. Para obtener más información y ejemplos, consulta Recorrido y normalización de rutas de acceso.
request.scheme cadena Es el esquema de URL HTTP, como http o https. Todos los valores de este atributo están en minúsculas.
request.query string Es la consulta de URL HTTP en el formato name1=value&name2=value2, como aparece en la primera línea de la solicitud HTTP. No se realiza ninguna decodificación.
origin.region_code cadena Es el código de país Unicode asociado con la IP del cliente, como US. Si creas una regla o expresión que use códigos de país o región ISO 3166-1 alfa 2, Cloud Armor tratará cada código de forma independiente. Las reglas y expresiones de Cloud Armor usan de forma explícita esos códigos de región para permitir o denegar solicitudes.
origin.asn integer Es el número de sistema autónomo (ASN) asociado con la dirección IP del cliente. El ASN único a nivel global se determina según el operador de red que admite los prefijos de dirección IP que contienen la dirección IP del cliente.

Atributos de reCAPTCHA

En esta sección, se enumeran los atributos que solo se aplican a tokens o cookies de exención de reCAPTCHA. Una subexpresión basada en estos atributos devuelve false si el token de reCAPTCHA o la cookie de exención que se evaluará no está disponible o no es válido por uno de los siguientes motivos:

  • El token tiene un formato incorrecto y no se puede decodificar.
  • El token contiene atributos no válidos. Por ejemplo, el token se generó con una clave de reCAPTCHA que no coincide con las claves de reCAPTCHA asociadas de la regla.
  • El token está vencido.
Campo Tipo Descripción del campo
token.recaptcha_exemption.valid bool La presencia de una cookie de exención de reCAPTCHA válida.

Atributos del token de acción

Campo Tipo Descripción del campo
token.recaptcha_action.score float La puntuación de un token de acción de reCAPTCHA Enterprise. Una puntuación válida varía de 0.0 a 1.0, donde 0.0 es muy probable que sea un usuario ilegítimo y 1.0 es muy probable que sea un usuario legítimo.
token.recaptcha_action.captcha_status string El estado del captcha de un token de acción de reCAPTCHA. Un estado válido es NONE, PASS o FAIL, en el que NONE hace referencia a que no hay desafíos involucrados durante la evaluación de reCAPTCHA, de modo que falta el campo de captcha en el token de acción.
token.recaptcha_action.action string El nombre de la acción (hasta 100 caracteres) de un token de acción de reCAPTCHA. Consulta Nombres de acciones.
token.recaptcha_action.valid bool La presencia de un token de acción de reCAPTCHA válido.

Atributos del token de sesión

Campo Tipo Descripción del campo
token.recaptcha_session.score float La puntuación de un token de sesión de reCAPTCHA. Una puntuación válida varía de 0.0 a 1.0, donde 0.0 es muy probable que sea un usuario ilegítimo y 1.0 es muy probable que sea un usuario legítimo.
token.recaptcha_session.valid bool La presencia de un token de sesión de reCAPTCHA válido.

Expresiones de ejemplo

Para cada una de estas expresiones, la acción que se realiza depende de si la expresión se incluye en una regla de denegación o de admisión.

Permite o deniega el acceso según un rango de direcciones IP en IPv4 o IPv6

  • La siguiente expresión coincide con las solicitudes del rango de direcciones IP 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24')
    
  • La siguiente expresión coincide con las solicitudes del rango de direcciones IP 2001:db8::/32:

    inIpRange(origin.ip, '2001:db8::/32')
    

Permite o deniega el acceso según un rango de direcciones IP de cliente personalizado detrás de un proxy upstream

Si configuraste el operador origin.user_ip, puedes establecer coincidencias en función de los valores de encabezado que especificaste en el campo advancedOptionsConfig.userIpRequestHeaders[].

  • La siguiente expresión coincide con las solicitudes que se originaron en el rango de direcciones IP 192.0.2.0/24:

    inIpRange(origin.user_ip, '192.0.2.0/24')
    
  • La siguiente expresión coincide con las solicitudes que se originaron en el rango de direcciones IP 2001:db8::/32:

    inIpRange(origin.user_ip, '2001:db8::/32')
    
  • La siguiente expresión coincide con las solicitudes que tienen una cookie que tiene 80=BLAH.

    has(request.headers['cookie']) && request.headers['cookie'].contains('80=BLAH')
    

Permite o deniega el tráfico con un encabezado referer que no esté vacío

  • La siguiente expresión coincide con las solicitudes que tienen un encabezado referer que no está vacío.

    has(request.headers['referer']) && request.headers['referer'] != ""
    

Permite o deniega el tráfico según el encabezado del host

Puedes permitir o denegar el tráfico según el valor del encabezado Host en la solicitud.

  • La siguiente expresión coincide con las solicitudes a una URL específica con ==:

    request.headers['host'].lower() == 'test.example.com'
    
  • La siguiente expresión coincide con las solicitudes a una URL específica con endsWith:

    request.headers['host'].lower().endsWith('.example.com')
    
  • La siguiente expresión coincide con las solicitudes a una URL específica con contains:

    request.headers['host'].lower().contains('test.example.com')
    
  • La siguiente expresión coincide con las solicitudes a varios dominios con contains:

    request.headers['host'].lower().contains('test.example.com') || request.headers['host'].lower().contains('test22.example.com')
    
  • La siguiente expresión coincide con las solicitudes de un dominio y sus subdominios con matches:

    request.headers['host'].matches('(?i:(?:sub\.)?test\.example\.com)')
    

Permite o deniega el tráfico desde una región específica

Si tu aplicación web no está disponible en la región AU, todas las solicitudes de esa región deben bloquearse.

  • En una regla de rechazo, usa la siguiente expresión, que coincide con las solicitudes de la región AU:

    origin.region_code == 'AU'
    

Como alternativa, si tu aplicación web solo está disponible en la región AU, se deben bloquear las solicitudes de todas las demás regiones.

  • En una regla de denegación, usa la siguiente expresión, que coincide con las solicitudes de todas las regiones que no sean AU:

    origin.region_code != 'AU'
    

Los códigos de región se basan en los códigos ISO 3166-1 alfa 2. En algunos casos, una región corresponde a un país, pero no siempre es así. Por ejemplo, el código US incluye todos los estados de Estados Unidos, un distrito y seis áreas periféricas.

Permite o deniega el tráfico desde un ASN específico

Si tu aplicación web debe bloquearse para los clientes a los que presta servicio un operador de red específico, puedes usar el número ASN del operador de red para realizar el bloqueo.

  • En una regla de denegación, usa la siguiente expresión, que coincide con las solicitudes de un ASN específico:

    origin.asn == 123
    

Como alternativa, si tu aplicación web está solo disponible para los clientes detrás de un operador de red específico, deben bloquearse las solicitudes de todos los demás operadores de red.

  • En una regla de denegación, usa la siguiente expresión, que coincide con todos los demás operadores de red, excepto el que te interesa permitir:

    origin.asn != 123
    

Expresiones múltiples

Para incluir varias condiciones en una sola regla, combina varias subexpresiones.

  • En el siguiente ejemplo, las solicitudes de 1.2.3.0/24 (como tus verificadores Alfa) en la región AU coinciden con la siguiente expresión:

    origin.region_code == "AU" && inIpRange(origin.ip, '1.2.3.0/24')
    
  • La siguiente expresión coincide con las solicitudes de 1.2.3.4 en las que un usuario-agente contiene la string WordPress:

    inIpRange(origin.ip, '1.2.3.4/32') &&
    has(request.headers['user-agent']) && request.headers['user-agent'].contains('WordPress')
    

Permite o deniega el tráfico para un URI de solicitud que coincida con una expresión regular

  • La siguiente expresión coincide con las solicitudes que contienen la string /example_path/ en el URI:

    request.path.matches('/example_path/')
    
  • La siguiente expresión coincide con las solicitudes que tienen Chrome en el campo de encabezado User-Agent:

    request.headers['user-agent'].matches('Chrome')
    
  • En la siguiente expresión, se muestra la coincidencia que no distingue mayúsculas de minúsculas para el encabezado User-Agent que contiene wordpress. Coincide con User-Agent:WordPress/605.1.15, User-Agent:wordPress y otras variantes de wordpress:

    request.headers['user-agent'].matches('(?i:wordpress)')
    

Permite o deniega el tráfico que contiene un valor decodificado en Base64 específico

  • La siguiente expresión coincide con las solicitudes que tienen un valor decodificado en Base64 de myValue para el encabezado user-id:

    has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')
    

Permite o deniega el tráfico que contiene un valor de cadena de una longitud específica

  • La siguiente expresión coincide con las solicitudes que tienen una longitud de URL superior a 10 caracteres:

    size(request.path) > 10
    
  • La siguiente expresión coincide con las solicitudes que tienen una longitud de encabezado x-data mayor o igual que 1,024 caracteres:

    size(request.headers['x-data']) >= 1024
    

Permite o deniega el tráfico que tiene una content-length de cero en el cuerpo HTTP

  • La siguiente expresión coincide con las solicitudes que tienen un content-length de cero en el cuerpo HTTP:

    int(request.headers["content-length"]) == 0
    

Permite o deniega el tráfico que contiene un valor codificado de URL específico

  • La siguiente expresión coincide con las solicitudes que tienen un valor de cookie que contiene %3c:

    has(request.headers['cookie']) && request.headers['cookie'].urlDecode().contains('<')
    

Permite o deniega el tráfico que contiene un valor codificado de URL específico de una cadena Unicode

  • La siguiente expresión coincide con las solicitudes que tienen un valor de cookie igual a Match%2BValue o Match%u002BValue:

    has(request.headers['cookie']) && request.headers['cookie'].urlDecodeUni() == 'Match+Value'
    

Permite o deniega el tráfico que contiene una string Unicode específica de un texto UTF-8

  • La siguiente expresión coincide con las solicitudes que tienen un valor de cookie igual a ¬:

    has(request.headers['cookie']) && request.headers['cookie'].utf8ToUnicode() == '%u00ac'
    

Permite o deniega el tráfico según una huella digital JA4 conocida

  • La siguiente expresión coincide con las solicitudes que tienen una huella digital JA4 igual a t13d1516h2_8daaf6152771_b186095e22b6:

    origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
    

Permite o deniega el tráfico según una lista de huellas digitales de JA4

  • La siguiente expresión coincide con las solicitudes que tienen una huella digital JA4 igual a cualquiera de las siguientes huellas digitales JA4:

    • t00d0000h0_000000000000_000000000000
    • t13d1516h2_8daaf6152771_b186095e22b6
    origin.tls_ja4_fingerprint == 't00d0000h0_000000000000_000000000000' || origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
    

Permite o deniega el tráfico según el contenido del cuerpo de la solicitud

  • La siguiente expresión coincide con las solicitudes POST que contienen malicious-value en el cuerpo de la solicitud:

    request.method == 'POST' && request.body.contains('malicious-value')
    
  • La siguiente expresión coincide con las solicitudes que comienzan con <!DOCTYPE html>:

    request.body.startsWith('<!DOCTYPE html>')
    
  • La siguiente expresión coincide con las solicitudes en las que el cuerpo coincide con la expresión regular \w+@\w+.com:

    request.body.matches('\w+@\w+.com')
    

Permite o deniega el tráfico según los parámetros de la solicitud

  • La siguiente expresión coincide con las solicitudes que no contienen un parámetro llamado category:

    !has(request.params.category)
    
  • La siguiente expresión coincide con las solicitudes en las que el parámetro category es electronics:

    request.params.category == 'electronics'
    
  • La siguiente expresión coincide con las solicitudes en las que todos los valores de los parámetros no están vacíos:

    request.params.all(k, request.params[k] != '')
    
  • La siguiente expresión coincide con las solicitudes en las que cualquier parámetro contiene la cadena admin:

    request.params.exists(k, request.params[k].contains('admin'))
    
  • La siguiente expresión coincide con las solicitudes en las que exactamente un nombre de parámetro contiene admin:

    request.params.exists_one(k, k.contains('admin'))
    
  • La siguiente expresión coincide con las solicitudes en las que al menos un nombre de parámetro contiene id:

    size(request.params.filter(k, k.contains('id'))) > 0
    
  • La siguiente expresión coincide con las solicitudes en las que los valores de los parámetros incluyen la cadena admin:

    request.params.map(k, request.params[k]).contains('admin')
    

Permite o deniega el tráfico según los datos estructurados en el cuerpo de la solicitud

  • La siguiente expresión coincide con las solicitudes en las que el campo password del cuerpo de la solicitud JSON contiene 123:

    has(request.params.password) && request.params.password.contains('123')
    
  • La siguiente expresión coincide con las solicitudes en las que el campo city de los datos del formulario es NewYork:

    has(request.params.city) && request.params.city == 'NewYork'
    
  • La siguiente expresión coincide con las solicitudes en las que el campo newsletter anidado es true:

    has(request.params.preferences) && has(request.params.preferences.newsletter) && request.params.preferences.newsletter == true
    
  • La siguiente expresión coincide con las solicitudes en las que el campo name del primer elemento del array friends es johndoe:

    request.params['friends'][0]['name'] == 'johndoe'
    

Reglas de WAF preconfiguradas

Las reglas de WAF preconfiguradas usan firmas estáticas preconfiguradas, expresiones regulares o ambas para coincidir con el cuerpo de la solicitud HTTP, los encabezados de la solicitud HTTP y los parámetros de consulta. Las reglas de WAF preconfiguradas disponibles se basan en el conjunto de reglas principales de OWASP 4.22. Cloud Armor proporciona varias reglas de WAF predefinidas. Para obtener una lista completa de las reglas de WAF preconfiguradas, consulta la descripción general de las reglas de WAF preconfiguradas de Cloud Armor.

Para obtener una lista de todas las reglas de WAF preconfiguradas, consulta Visualiza las reglas de WAF preconfiguradas.

Para obtener más información sobre las reglas de WAF preconfiguradas, consulta el caso de uso Mitiga los ataques de la capa de aplicación con reglas de WAF preconfiguradas.

Nombres de reglas de WAF preconfiguradas

Los nombres de reglas de WAF preconfigurados tienen el formato <attack category>-<OWASP CRS version>-<version field>. La categoría de ataque especifica el tipo de ataques de lo que te quieres proteger, como xss (secuencia de comandos entre sitios) o sqli (inyección de SQL).

Los campos de versiones compatibles son stable y canary. Las adiciones y modificaciones a las reglas se publican primero en la versión canary. Cuando las incorporaciones y modificaciones se consideran seguras y estables, se ascienden a la versión stable.

ID de miembros de reglas de WAF preconfigurados

Una regla de WAF preconfigurada contiene varias expresiones, cada una con su firma. Por ejemplo, la regla de WAF preconfigurada xss-v422-stable incluye una expresión llamada owasp-crs-v042200-id941100-xss, que corresponde al ID de regla id941100 para la versión 4.22. Puedes usar las firmas para excluir el uso de expresiones específicas, lo que es útil si una expresión en particular siempre activa un falso positivo. Para obtener más información, consulta la información sobre solución de problemas de falsos positivos.

Para obtener información sobre el conjunto de reglas principales y el ajuste en diferentes niveles de sensibilidad, consulta Ajusta las reglas de WAF de Cloud Armor.

Operador para reglas de WAF preconfiguradas

Expresiones Descripción
evaluatePreconfiguredWaf(string, MAP<string, dyn>) Devuelve true si alguna de las firmas de WAF dentro del conjunto de reglas de WAF especificado devuelve true. El primer argumento es el nombre del conjunto de reglas de WAF, como xss-v422-stable. El segundo argumento (opcional) es un mapa en el que la clave es una string y el valor se escribe de forma dinámica según la clave. El propósito de este argumento es ajustar las firmas de WAF que se evalúan. Entre las claves aceptadas, se incluyen las siguientes:
  • sensitivity: Corresponde al nivel de paranoia del conjunto de reglas principales de OWASP, que tiene 4 niveles, desde 1 hasta 4. Su valor es un número entero con un rango válido de 0 a 4. Ten en cuenta que 0 se reserva como un valor válido cuando se usa en combinación con opt_in_rule_ids (que se describe más adelante). Cuando se especifica una sensibilidad de x (x >= 1), se evalúan todas las firmas de WAF asociadas con un valor de sensibilidad de 1 a x. Cuando se omite, se usa 4 como el valor de sensibilidad.
  • opt_out_rule_ids: Son las firmas de WAF (representadas por los IDs de regla) que se deben inhabilitar de la evaluación, en las que el conjunto base se determina según el valor de sensibilidad. Su valor es una lista de strings. La cantidad máxima de IDs de reglas permitidos es 128.
  • opt_in_rule_ids: Son las firmas de WAF (representadas por los IDs de regla) que se deben habilitar para la evaluación, en las que el conjunto base está vacío. Su valor es una lista de strings. La cantidad máxima de IDs de reglas permitidos es 128. Cuando se usa, se debe especificar un sensitivity de 0.

Las claves opt_out_rule_ids y opt_in_rule_ids son mutuamente excluyentes. Puedes usar opt_in_rule_ids si quieres revisar y habilitar manualmente las firmas nuevas de WAF que se agregan más adelante en un conjunto de reglas existente.

evaluatePreconfiguredWaf(string, LIST)

Devuelve true si alguna de las expresiones dentro de la regla de WAF preconfigurada especificada devuelve true.

El primer argumento es el nombre de la regla de WAF preconfigurada, como xss-stable. El segundo argumento (opcional) es una lista de cadenas separada por comas de los IDs que se deben excluir de la evaluación. La lista de exclusiones es útil cuando un miembro determinado de la regla de WAF preconfigurada activa un falso positivo.

Ejemplos de reglas de WAF preconfiguradas

  • En la siguiente expresión, se usa la regla de WAF preconfigurada xss-v422-stable para mitigar los ataques de XSS:

    evaluatePreconfiguredWaf('xss-v422-stable')
    
  • En la siguiente expresión, se usan todas las expresiones de la regla de WAF preconfigurada xss-v422-stable, excepto los ID de miembro 941100 y 941110:

    evaluatePreconfiguredWaf('xss-v422-stable', {'opt_out_rule_ids': ['owasp-crs-v042200-id941100-xss',
    'owasp-crs-v042200-id941110-xss']})
    
  • En la siguiente expresión, se usa una regla de WAF preconfigurada para mitigar los ataques de SQLi desde el rango de direcciones IP 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredWaf('sqli-v422-stable')
    
  • En la siguiente expresión, se usa la regla de WAF preconfigurada xss-v422-stable para mitigar los ataques de XSS en las solicitudes a example.com, excepto las rutas de acceso que comienzan con /login/api/:

    request.headers['host'].lower() == 'example.com' && !request.path.startswith('/login/api/') && evaluatePreconfiguredWaf('xss-v422-stable')
    

Reglas administradas

Las reglas administradas de Google Cloud Armor protegen tus apps web y endpoints de API con firmas de seguridad que se actualizan automáticamente. Las reglas administradas se basan en Thales Imperva y se integran directamente en Cloud Armor, lo que simplifica tus operaciones de seguridad. Las reglas administradas eliminan la necesidad de actualizar las firmas de forma manual y reducen el desvío de configuración, lo que permite que tu equipo de seguridad se enfoque en el desarrollo y las operaciones.

Operador para reglas administradas

Expresiones Descripción
evaluateManagedRules(string, MAP<string, dyn>) Devuelve true si alguna de las firmas dentro de las reglas administradas especificadas devuelve true. El primer argumento es el nombre completamente calificado de la categoría, como google:xss:stable o google:sqli:canary. El segundo argumento (opcional) es un mapa en el que la clave es una cadena y el valor se escribe de forma dinámica según la clave. Entre las claves aceptadas, se incluyen las siguientes:
  • opt_in_rule_ids: Es una lista de IDs de reglas del conjunto de reglas correspondiente que son las únicas reglas que se evalúan. Por ejemplo, evaluateManagedRules('google:xss:canary', {'opt_in_rule_ids': ['google-xss-8057544707029182464']})
  • opt_out_rule_ids: Es una lista de IDs de reglas del conjunto de reglas correspondiente que se excluyen de la evaluación. Por ejemplo, evaluateManagedRules('google:xss:canary', {'opt_out_rule_ids': ['google-xss-8057544707029182464']})

Ejemplos de reglas administradas

  • En la siguiente expresión, se usan las reglas administradas estables de inyección de SQL (sqli) para ayudar a prevenir los ataques de SQLi:

    evaluateManagedRules('google:sqli:stable')
    
  • En la siguiente expresión, se usan las reglas administradas xss estables solo si la solicitud tiene el host example.com:

    request.headers['host'].lower() == 'example.com' && evaluateManagedRules('google:xss:stable')
    

Otros operadores

Expresiones Descripción
evaluateThreatIntelligence(string)
evaluateThreatIntelligence(string, LIST)
evaluateThreatIntelligence(string, string, LIST)

Devuelve true si la dirección IP del cliente coincide con alguno de los rangos de IP de la lista de IP proporcionada, a menos que se excluya de forma explícita con la lista de exclusión.

El primer argumento es el nombre del feed de Google Threat Intelligence, como iplist-known-malicious-ips. Si el segundo argumento es una cadena (opcional), determina de dónde se extrae la dirección IP y puede ser origin.ip, origin.user_ip o un nombre de encabezado específico. Si el segundo o tercer argumento (opcional) es una lista separada por comas de cadenas, en la que cada cadena es una dirección IP o un rango CIDR, se excluirá de la evaluación. La lista de exclusiones es útil cuando un feed contiene alguna dirección IP que activa un falso positivo.

evaluateAddressGroup(string, string)
evaluateAddressGroup(string, string, LIST)

evaluateOrganizationAddressGroup(string, string)
evaluateOrganizationAddressGroup(string, string, LIST)

Devuelve true si la dirección IP del cliente coincide con alguno de los rangos de IP del grupo de direcciones determinado, a menos que se excluya de forma explícita con la lista de exclusión.

El primer argumento es el nombre del grupo de direcciones. El segundo argumento determina de dónde se extrae la dirección IP y puede ser origin.ip, origin.user_ip o un nombre de encabezado específico. El tercer argumento (opcional) es una lista separada por comas de cadenas, en la que cada cadena es una dirección IP o un rango CIDR, que se excluirá de la evaluación. La lista de exclusiones es útil cuando un grupo de direcciones contiene alguna dirección IP que activa un falso positivo.

evaluateAdaptiveProtection(string)

Devuelve true si la solicitud coincide con la firma de ataque producida por la Protección adaptable de Google Cloud Armor.

El argumento es el ID de una alerta específica que genera la Protección adaptable cuando detecta un ataque.

evaluateAdaptiveProtectionAutoDeploy()

Devuelve true si la solicitud proviene de una dirección IP de un atacante frecuente que coincide con la firma de un ataque en curso detectado por la Protección adaptable.

Ejemplos

  • La siguiente expresión compara la solicitud entrante con el feed de Google Threat Intelligence iplist-known-malicious-ips para protegerla de la lista conocida de IPs maliciosas:

    evaluateThreatIntelligence('iplist-known-malicious-ips')
    
  • La siguiente expresión compara la solicitud entrante con el feed de Google Threat Intelligence iplist-known-malicious-ips para protegerla de la lista conocida de IPs maliciosas, excepto las IPs en 203.0.113.0/24:

    evaluateThreatIntelligence('iplist-known-malicious-ips', ['203.0.113.0/24'])
    
  • La siguiente expresión hace coincidir el encabezado de la solicitud personalizado para la IP del usuario con el grupo de direcciones llamado my-own-list-of-bad-ips:

    evaluateAddressGroup('my-own-list-of-bad-ips', origin.user_ip)
    

¿Qué sigue?