Configurar atributos de linguagem de regras personalizadas

Cada regra da política de segurança do Google Cloud Armor tem uma prioridade, uma condição de correspondência e uma ação. O Google Cloud Armor executa a ação da regra de prioridade mais alta que corresponda a uma solicitação. As regras com prioridade mais baixa do que a regra de correspondência de maior prioridade não são avaliadas, mesmo que tenham as mesmas condições de correspondência.

Cada regra da política de segurança é compatível com dois tipos de condições de correspondência:

  • Uma condição de correspondência básica contém listas de endereços IP ou de intervalos de endereços IP. As condições de correspondência básicas são definidas usando a flag --src-ip-ranges ao criar uma regra usando a CLI do Google Cloud.
  • Uma condição de correspondência avançada contém uma expressão com até cinco subexpressões que podem corresponder a diversos atributos de uma solicitação recebida. As condições de correspondência avançadas são definidas usando a flag --expression ao criar uma regra usando a CLI do Google Cloud.

Nesta página, você vai aprender sobre condições avançadas de correspondência e o linguagem de regras personalizadas que você usa para escrever expressões na correspondência avançada das regras da política de segurança. A linguagem das regras personalizadas do Google Cloud Armor é um subconjunto da Common Expression Language (CEL). As expressões escritas na linguagem de regras personalizadas do Google Cloud Armor exigem dois componentes:

  • O atributo: os dados a serem inspecionados
  • A operação: como usar os dados

Por exemplo, a expressão a seguir usa os atributos origin.ip e 9.9.9.0/24 na operação inIpRange(). Nesse caso, a expressão retornará como verdadeiro se origin.ip estiver dentro do intervalo de endereços IP de 9.9.9.0/24.

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

Embora a expressão de exemplo anterior corresponda apenas ao endereço IP de origem, ao usar a expressão de exemplo em uma política de segurança do Google Cloud Armor regra, ela será considerada uma regra com condições de correspondência avançadas de uma de cotas. Para mais informações, consulte Cotas e limites do Google Cloud Armor.

Atributos

Os atributos representam informações de uma solicitação recebida, como o endereço IP de origem ou o caminho do URL solicitado.

Campo Tipo Descrição do campo
origin.ip string O endereço IP de origem da solicitação.
origin.user_ip string O endereço IP do cliente de origem, que está incluído no HTTP-HEADER por um proxy upstream. Antes de usar esse atributo, configure a opção userIpRequestHeaders[] no campo advancedOptionsConfig da política de segurança para corresponder a uma origem como True-Client-IP, X-Forwarded-For ou X-Real-IP.

Se você não configurar a opção userIpRequestHeaders[], se o cabeçalho configurado contiver valores de endereço IP inválidos ou se o cabeçalho configurado não estiver presente, origin.user_ip assumirá origin.ip como padrão. Para mais informações, consulte a referência do recurso securityPolicy.

origin.tls_ja3_fingerprint string Impressão digital TLS/SSL do JA3 se o cliente se conectar usando HTTPS, HTTP/2 ou HTTP/3. Se não estiver disponível, uma string vazia será retornada.
request.headers mapa Um mapa string a string dos cabeçalhos de solicitação HTTP. Se um cabeçalho contiver vários valores, o valor nesse mapa seria uma string separada por vírgula de todos os valores do cabeçalho. As chaves deste mapa ficam todas em minúsculas. Todos os cabeçalhos aceitos pelos balanceadores de carga de aplicativo externos são inspecionados e as mesmas limitações de cabeçalho se aplicam.

A abordagem recomendada é verificar primeiro a disponibilidade usando has(), como has(request.headers['header-key']) && request.headers['header-key'] != 'header-value'.

request.method string O método de solicitação HTTP, como GET ou POST.
request.path string O caminho do URL de HTTP solicitado.
request.scheme string O esquema de URL HTTP, como http ou https. Os valores deste atributo ficam todos em minúsculas.
request.query string A consulta de URL de HTTP no formato name1=value&name2=value2, conforme aparece na primeira linha da solicitação HTTP. Nenhuma decodificação é executada.
origin.region_code string O código do país em Unicode associado ao IP de origem, como US. Se você estiver criando uma regra ou expressão que usa códigos de país ou região ISO 3166-1 Alfa 2, o Google Cloud Armor tratará cada código de maneira independente. As regras e expressões do Google Cloud Armor usam explicitamente esses códigos de região para permitir ou negar solicitações.

Saiba mais em unicode_region_subtag no Unicode Technical Standard.

origin.asn integer O número de sistema autônomo (ASN, na sigla em inglês) associado ao endereço IP de origem. O ASN globalmente exclusivo é determinado com base no operador de rede que aceita os prefixos de endereço IP que contêm o endereço IP de origem.

Atributos do reCAPTCHA

Nesta seção, listamos os atributos que se aplicam apenas a tokens reCAPTCHA ou cookies de isenção. Uma subexpressão com base nesses atributos, retornará false se o token reCAPTCHA ou isenção o cookie a ser avaliado não está disponível ou é inválido para um dos seguintes motivos:

  • O token é mal desenvolvido e não pode ser decodificado.
  • O token contém atributos inválidos. Por exemplo, o token foi gerado usando uma chave do reCAPTCHA que não corresponde às chaves do reCAPTCHA associadas à regra.
  • O token expirou.
Campo Tipo Descrição do campo
token.recaptcha_exemption.valid bool Presença de um cookie de isenção reCAPTCHA válido.

Atributos de token de ação

Campo Tipo Descrição do campo
token.recaptcha_action.score float A pontuação de um token de ação reCAPTCHA. Uma pontuação válida varia de 0.0 a 1.0, sendo 0.0 um usuário muito ilegítimo e 1.0 muito legítimo.
token.recaptcha_action.captcha_status string O status do CAPTCHA de um token de ação reCAPTCHA. Um status válido é NONE, PASS ou FAIL, em que NONE se refere a quando não há desafios envolvidos durante a avaliação do reCAPTCHA, de modo que o captcha esteja ausente no token de ação.
token.recaptcha_action.action string O nome da ação (até 100 caracteres) de um token de ação do reCAPTCHA. Consulte Nomes de ação.
token.recaptcha_action.valid bool A presença de um token de ação reCAPTCHA válido.

Atributos do token de sessão

Campo Tipo Descrição do campo
token.recaptcha_session.score float A pontuação de um token de sessão reCAPTCHA. Uma pontuação válida varia de 0.0 a 1.0, sendo 0.0 um usuário muito ilegítimo e 1.0 muito legítimo.
token.recaptcha_session.valid bool A presença de um token de sessão reCAPTCHA válido.

Operações

A referência a seguir descreve os operadores que podem ser usados com atributos (representados por x, y e k) para definir expressões de regra.

Expressões Descrição
x == "foo" Retorna como verdadeiro se x for igual à literal de string constante fornecida.
x == R"fo'o" Retorna como verdadeiro se x for igual à literal de string bruta fornecida que não interpreta sequências de escape. As literais de string bruta são convenientes para expressar strings que precisam usar caracteres de sequência de escape.
x == y Retorna TRUE, se x for igual a y.
x != y Retorna TRUE, se x não for igual a y.
x + y Retorna a string concatenada xy .
x && y Retorna como verdadeiro se x e y forem verdadeiros.
x || y Retorna como verdadeiro se x, y ou ambos forem verdadeiros.
!x Retorna como verdadeiro se o valor booleano x for falso ou retorna como falso se o valor booleano x for verdadeiro.
x.contains(y) Retorna como verdadeiro se a string x contiver a substring y.
x.startsWith(y) Retorna como verdadeiro se a string x começar com a substring y.
x.endsWith(y) Retorna como verdadeiro se a string x terminar com a substring y.
x.matches(y) Retorna "true" se a string x é parcialmente correspondida pelo RE2 padrão y. O padrão RE2 é compilado usando a opção RE2::Latin1 que desativa os recursos Unicode.
inIpRange(x, y) Retorna como verdadeiro se o endereço IP x estiver dentro do intervalo IP de y
x.lower() Retorna o valor em minúsculas da string x.
x.upper() Retorna o valor em maiúsculas da string x.
x.base64Decode() Retorna o valor de x. decodificado em Base64; os caracteres _ - são substituídos primeiro por / + respectivamente. Retorna "" (string vazia) se x não for um valor base64 válido.
has(m['k']) Retorna como verdadeiro se a chave k. estiver disponível no mapa m.
m['k'] Retorna o valor na chave k no mapa string a string m. se k estiver disponível, caso contrário, retorna um erro. A abordagem recomendada é verificar a disponibilidade usando "has(m['k'])==true".
int(x) Converte o resultado da string de x em um tipo int. Ele pode ser usado para fazer uma comparação de números inteiros usando operadores aritméticos padrão, como > e <=. Isso funciona apenas para valores que precisam ser inteiros.
size(x) Retorna o comprimento da string x.
x.urlDecode() Retorna o valor decodificado de URL de x. As sequências de caracteres no formato %## são substituídas por equivalentes não ASCII, e + é substituído por um espaço. As codificações inválidas retornam como estão.
x.urlDecodeUni() Retorna o valor decodificado de URL de x. Além de urlDecode() e também processa sequências de caracteres Unicode no formato %u###. As codificações inválidas retornam como estão.
x.utf8ToUnicode() Retorna a representação Unicode de letras minúsculas de um x codificado em UTF-8.

Exemplos de expressões

Para cada uma dessas expressões, a ação realizada depende de a expressão ser incluída em uma regra de negação ou em uma regra de permissão.

Permitir ou negar acesso com base em um intervalo de endereços IP em IPv4 ou IPv6

  • A expressão a seguir corresponde às solicitações do intervalo de endereços IP 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24')
    
  • A expressão a seguir corresponde às solicitações do intervalo de endereços IP 2001:db8::/32:

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

Permitir ou negar acesso com base em um intervalo de endereços IP de cliente personalizados protegido por um proxy upstream

Se você tiver configurado o operador origin.user_ip, poderá fazer a correspondência com base nos valores de cabeçalho que foram especificados no campo advancedOptionsConfig.userIpRequestHeaders[].

  • A seguinte expressão faz a correspondência com solicitações originadas do intervalo de endereços IP 192.0.2.0/24:

    inIpRange(origin.user_ip, '192.0.2.0/24')
    
  • A seguinte expressão faz a correspondência com solicitações originadas do intervalo de endereços IP 2001:db8::/32:

    inIpRange(origin.user_ip, '2001:db8::/32')
    
  • A expressão a seguir corresponde a solicitações que têm um cookie contendo 80=BLAH:

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

Permitir ou negar tráfego com um cabeçalho referer não vazio

  • A expressão a seguir corresponde a solicitações que têm um cabeçalho referer não vazio:

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

Permitir ou negar tráfego com base no URL do host no cabeçalho

  • A expressão a seguir corresponde a solicitações para um URL específico:

    request.headers['host'].lower().contains('test.example.com')
    

Permitir ou negar o tráfego de uma região específica

Se o aplicativo da Web não estiver disponível na região AU, todas as solicitações dessa região precisarão ser bloqueadas.

  • Em uma regra de negação, use a seguinte expressão, que corresponde a solicitações da região AU:

    origin.region_code == 'AU'
    

Como alternativa, se o aplicativo da Web estiver disponível apenas na região AU, as solicitações de todas as outras regiões precisarão ser bloqueadas.

  • Em uma regra de negação, use a seguinte expressão, que corresponde a solicitações de todas as regiões diferentes da região AU:

    origin.region_code != 'AU'
    

Os códigos de região são baseados nos códigos ISO 3166-1 alpha 2. Em alguns casos, uma região corresponde a um país, mas nem sempre é o caso. Por exemplo, o código US inclui todos os estados dos Estados Unidos, um distrito e seis áreas remotas.

Permitir ou negar o tráfego de um ASN específico

Se o aplicativo da Web precisar ser bloqueado para clientes atendidos por um operador de rede específico, use o número ASN do operador de rede para bloquear.

  • Em uma regra de negação, use a seguinte expressão, que corresponde às solicitações de um ASN específico:

    origin.asn == 123
    

Como alternativa, se o aplicativo da Web estiver apenas disponível para os clientes por trás de um operador de rede específico, as solicitações de todos os outros operadores de rede precisarão ser bloqueadas.

  • Em uma regra de negação, use a seguinte expressão, que corresponde a todos os outros operadores de rede diferentes daquele que você está permitindo.

    origin.asn != 123
    

Várias expressões

Para incluir várias condições em apenas uma regra, combine várias subexpressões.

  • No exemplo a seguir, solicitações de 1.2.3.0/24 (como seus testadores alfa) na região AU correspondem à seguinte expressão:

    origin.region_code == "AU" && inIpRange(origin.ip, '1.2.3.0/24')
    
  • A expressão a seguir corresponde a solicitações de 1.2.3.4 em que um user agent contém a string WordPress:

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

Permitir ou negar tráfego para um URI de solicitação que corresponda a uma expressão regular

  • A expressão a seguir corresponde a solicitações que contêm a string example_path no URI:

    request.path.matches('/example_path/')
    
  • A expressão a seguir corresponde a solicitações que têm Chrome no campo de cabeçalho User-Agent:

    request.headers['user-agent'].matches('Chrome')
    
  • A expressão a seguir mostra uma correspondência que não diferencia maiúsculas de minúsculas para o cabeçalho User-Agent que contém wordpress; corresponde a User-Agent:WordPress/605.1.15, User-Agent:wordPress e outras variações de wordpress:

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

Permitir ou negar tráfego que contém um valor decodificado em Base64 específico

  • A expressão a seguir corresponde a solicitações que têm um valor decodificado em Base64 de myValue para o cabeçalho user-id:

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

Permitir ou negar tráfego que contém um valor de string de tamanho específico

  • A expressão a seguir corresponde a solicitações que têm um comprimento de URL maior que 10 caracteres:

    size(request.path) > 10
    
  • A expressão a seguir corresponde a solicitações que têm um comprimento de cabeçalho x-data maior ou igual a 1.024 caracteres:

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

Permitir ou negar tráfego que tenha o valor zero content-length no corpo HTTP

  • A expressão a seguir corresponde a solicitações que têm um content-length zero no corpo do HTTP:

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

Permitir ou negar tráfego que tenha um valor codificado de URL específico

  • A expressão a seguir corresponde a pedidos que têm um cookie contendo %3c:

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

Permitir ou negar o tráfego que contém um valor específico codificado de uma string Unicode

  • A expressão a seguir corresponde a pedidos com um valor de cookie igual a Match%2BValue ou Match%u002BValue.

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

Permitir ou negar tráfego que contenha uma string Unicode específica de um texto UTF-8

  • A expressão a seguir corresponde a pedidos com um valor de cookie igual a ¬.

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

Permitir ou negar tráfego com base em uma impressão digital conhecida do JA3

  • A expressão a seguir corresponde a solicitações que têm uma impressão digital JA3 igual a e7d705a3286e19ea42f587b344ee6865:

    origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865'
    

Permitir ou negar tráfego com base em uma lista de impressões digitais do JA3

  • A expressão a seguir corresponde a solicitações que têm uma impressão digital JA3 igual a qualquer uma das seguintes impressões digitais JA3:

    • e7d705a3286e19ea42f587b344ee6865
    • f8a5929f8949e846267b582072e35f84
    • 8f8b62163873a62234c14f15e7b88340
    origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865' || origin.tls_ja3_fingerprint == 'f8a5929f8949e846267b582072e35f84' || origin.tls_ja3_fingerprint == '8f8b62163873a62234c14f15e7b88340'
    

Regras pré-configuradas do WAF

As regras WAF pré-configuradas usam assinaturas estáticas pré-configuradas, expressões regulares ou ambas para corresponder aos corpos HTTP POST, cabeçalhos de solicitação HTTP e parâmetros de consulta. As regras de WAF pré-configuradas disponíveis são baseadas no conjunto de regras principais do OWASP Modsecurity para a versão 3.3. O Google Cloud Armor fornece várias regras WAF pré-configuradas predefinidas. Para uma lista completa de regras WAF pré-configuradas, consulte a Visão geral das regras WAF pré-configuradas do Google Cloud Armor.

Para listar todas as regras WAF pré-configuradas disponíveis, consulte Listar regras WAF pré-configuradas disponíveis.

Para mais informações sobre regras WAF pré-configuradas, consulte o caso de uso Reduzir ataques de camada de aplicativo usando regras WAF pré-configuradas.

Nomes das regras WAF pré-configuradas

Os nomes das regras WAF pré-configurados têm o formato <attack category>-<ModSecurity CRS version>-<version field>. A categoria de ataque especifica o tipo de ataque que você quer proteger, como xss (scripts entre sites) ou sqli (injeção de SQL).

Os campos de versão compatíveis são stable e canary. Adições e modificações nas regras são lançadas primeiro na versão canary. Quando as adições e modificações são consideradas seguras e estáveis, elas são promovidas à versão stable.

IDs de membros da regra WAF pré-configurada

Uma regra WAF pré-configurada contém várias expressões, cada uma com sua assinatura. Por exemplo, a regra WAF pré-configurada xss-v33-stable inclui uma expressão chamada owasp-crs-v030301-id941100-xss, que corresponde ao ID da regra id941100 para a versão 3.3. É possível usar as assinaturas para excluir o uso de expressões específicas, o que é útil se uma expressão específica acionar constantemente um falso positivo. Veja mais informações na solução de problemas de falsos positivos.

Para informações sobre o conjunto de regras principais e ajuste em diferentes níveis de sensibilidade, consulte Como ajustar as regras da WAF do Google Cloud Armor.

Operador para regras WAF pré-configuradas

Expressões Descrição
evaluatePreconfiguredWaf(string, MAP<string, dyn>) Retorna verdadeiro se qualquer uma das assinaturas WAF dentro do conjunto de regras WAF especificado retornar verdadeiro. O primeiro é o nome do conjunto de regras WAF, como xss-v33-stable. O segundo argumento (opcional) é um mapa em que a chave é uma string, e o valor é digitado dinamicamente, dependendo da chave. O objetivo deste argumento é ajustar as assinaturas WAF que são avaliadas. As chaves aceitas incluem:
  • "sensitivity": corresponde ao nível de paranóia do conjunto de regras principais do ModSecurity, que tem quatro níveis, variando de 1 a 4. O valor dela é um número inteiro com um intervalo válido de 0 a 4. 0 é reservado como um valor válido quando usado em combinação com "opt_in_rule_ids" (descrito posteriormente). Ao especificar uma sensibilidade de x (x >= 1), todas as assinaturas WAF associadas com um valor de sensibilidade de 1 a x são avaliadas. Quando omitido, o valor 4 é usado como o valor da sensibilidade.
  • "opt_out_rule_ids": assinaturas WAF (representadas por IDs de regra) para serem desativadas na avaliação, em que o conjunto base é determinado pelo valor da sensibilidade. O valor dela é uma lista de strings. O número máximo de IDs de regras permitidos é 128.
  • "opt_in_rule_ids": assinaturas WAF (representadas por IDs de regra) a serem ativadas para avaliação, em que o conjunto básico está vazio. O valor dela é uma lista de strings. O número máximo de IDs de regras permitidos é 128. Ao usar esse atributo, é necessário especificar uma "sensibilidade" de 0.

As chaves "opt_out_rule_ids" e "opt_in_rule_ids" são mutuamente exclusivas. Você pode usar "opt_in_rule_ids" se quiser revisar e ativar manualmente novas assinaturas WAF que forem adicionadas mais tarde em um conjunto de regras existente.

evaluatePreconfiguredExpr(string, LIST)

Retorna verdadeiro se qualquer uma das expressões dentro da regra WAF pré-configurada especificada retornar verdadeiro.

O primeiro é o nome da regra WAF pré-configurada, como xss-stable. O segundo argumento (opcional) é uma lista string de IDs separados por vírgulas que devem ser excluídos da avaliação. A lista de exclusão é útil quando um membro específico da regra WAF pré-configurada aciona um falso positivo.

Exemplos de regras WAF pré-configuradas

  • A expressão a seguir usa a regra WAF pré-configurada xss-v33-stable para mitigar ataques XSS:

    evaluatePreconfiguredExpr('xss-v33-stable')
    
  • A expressão a seguir usa todas as expressões da regra WAF pré-configurada xss-v33-stable, exceto os IDs de membro 941100 e 941110:

    evaluatePreconfiguredExpr('xss-v33-stable', ['owasp-crs-v030301-id941100-xss',
    'owasp-crs-v030301-id941110-xss'])
    
  • A expressão a seguir usa uma regra WAF pré-configurada para mitigar ataques SQLi do intervalo de endereços IP 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredExpr('sqli-v33-stable')
    

A seguir