Cada regra de política de segurança do Google Cloud Armor tem uma prioridade, uma condição de correspondência e uma ação. O Cloud Armor realiza a ação da regra de maior prioridade que corresponde a uma solicitação. As regras com uma prioridade menor que a regra de correspondência de prioridade mais alta não são avaliadas, mesmo que tenham as mesmas condições de correspondência.
Cada regra de política de segurança aceita 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 básicas de correspondência são definidas usando a flag --src-ip-rangesao criar uma regra com a Google Cloud CLI.
- 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çada são definidas usando a flag --expressionao criar uma regra com a CLI do Google Cloud.
Esta página aborda as condições de correspondência avançadas e a linguagem de regras personalizadas do Cloud Armor, que você usa para escrever expressões nas condições de correspondência avançadas das regras de política de segurança. A linguagem de regras personalizadas do Cloud Armor é um subconjunto da Common Expression Language (CEL). As expressões escritas na linguagem de regras personalizadas do 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, quando você usa a expressão de exemplo em uma regra de política de segurança do Cloud Armor, a regra é considerada uma regra com condições de correspondência avançadas de uma perspectiva de cota. Para mais informações, consulte Cotas e limites do Cloud Armor.
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.
| Operações | Expressões | Descrição | 
|---|---|---|
| Igualdade | x == y | Retorna TRUE, se x for igual a y. | 
| Igualdade, literal de string | x == "foo" | Retorna como verdadeiro se x for igual à literal de string constante fornecida. | 
| Igualdade, literal de string bruta | 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. | 
| Lógico NOT | !x | Retorna "true" se o valor booleano x for falso ou retorna "false" se o valor booleano x for "true". | 
| Desigualdade | x != y | Retorna TRUE, se x não for igual a y. | 
| Concatenação | x + y | Retorna a string concatenada xy . | 
| Lógico AND | x && y | Retorna como verdadeiro se x e y forem verdadeiros. | 
| Lógico OR | x || y | Retorna como verdadeiro se x, y ou ambos forem verdadeiros. | 
| Contém substring | x.contains(y) | Retorna como verdadeiro se a string x contiver a substring y. | 
| Começa com a substring | x.startsWith(y) | Retorna como verdadeiro se a string x começar com a substring y. | 
| Termina com substring | x.endsWith(y) | Retorna como verdadeiro se a string x terminar com a substring y. | 
| Correspondência de expressão regular | x.matches(y) | Retorna "true" se a string x corresponder parcialmente ao padrão RE2 especificado y. O padrão RE2 é compilado usando a opção RE2::Latin1 que desativa os recursos Unicode. | 
| Endereço IP dentro do intervalo | inIpRange(x, y) | Retorna "true" se o endereço IP x estiver dentro do intervalo IP de y. | 
| Letras minúsculas | x.lower() | Retorna o valor em minúsculas da string x. | 
| Uppercase | x.upper() | Retorna o valor em maiúsculas da string x. | 
| Valor decodificado em Base64 | 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. | 
| Valor do mapa de teclas | 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". | 
| Verificar a disponibilidade de chaves em um mapa | has(m['k']) | Retorna como verdadeiro se a chave k. estiver disponível no mapa m. | 
| Converter para número inteiro | 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. | 
| Duração | size(x) | Retorna o comprimento da string x. | 
| Decodificar URL | 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 são retornadas
      como estão. | 
| Decodificar URL (Unicode) | x.urlDecodeUni() | Retorna o valor decodificado de URL de x. Além de urlDecode(), também processa sequências de caracteres Unicode no
      formato%u###. As codificações inválidas retornam como estão. | 
| Converter utf8 em Unicode | x.utf8ToUnicode() | Retorna a representação Unicode de letras minúsculas de um x codificado em UTF-8. | 
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, incluído no HTTP-HEADERpor um proxy upstream. Antes de usar esse
      atributo, configure a opçãouserIpRequestHeaders[]no campoadvancedOptionsConfigda política de segurança
      para corresponder a uma origem comoTrue-Client-IP,X-Forwarded-ForouX-Real-IP.Se você não configurar a opção  | 
| origin.tls_ja4_fingerprint | string | Impressão digital TLS/SSL JA4
      se o cliente se conecta usando HTTPS,HTTP/2ouHTTP/3. Se não estiver disponível, uma string vazia será retornada. | 
| origin.tls_ja3_fingerprint | string | Impressão digital TLS/SSL JA3
      se o cliente se conectar usando HTTPS,HTTP/2ouHTTP/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 a disponibilidade usando  | 
| request.method | string | O método de solicitação HTTP, como GETouPOST. | 
| request.path | string | O caminho do URL de HTTP solicitado. | 
| request.scheme | string | O esquema de URL HTTP, como httpouhttps.
      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 Cloud Armor tratará cada código de maneira independente. As regras e expressões do Cloud Armor usam explicitamente esses códigos de região para permitir ou negar solicitações. | 
| 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 aplicáveis somente a
tokens reCAPTCHA ou cookies de isenção. Uma subexpressão com base nesses atributos retornará false se o token do reCAPTCHA ou o cookie de isenção a ser avaliado não estiver disponível ou for inválido por 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.
Atributos de cookies de isenção
| 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.0a1.0, sendo0.0um usuário muito
        ilegítimo e1.0muito
        legítimo. | 
| token.recaptcha_action.captcha_status | string | O status do CAPTCHA de um token de ação reCAPTCHA. Um status válido é NONE,PASSouFAIL, em queNONEse 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.0a1.0, sendo0.0um usuário muito
        ilegítimo e1.0muito
        legítimo. | 
| token.recaptcha_session.valid | bool | A presença de um token de sessão reCAPTCHA válido. | 
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') 
Permitir ou negar tráfego com um cookie específico
- 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 - referernão vazio:- has(request.headers['referer']) && request.headers['referer'] != "" 
Permitir ou negar tráfego com base no cabeçalho do host
É possível permitir ou negar o tráfego com base no valor do cabeçalho Host na solicitação.
- A expressão a seguir corresponde a solicitações para um URL específico usando - ==:- request.headers['host'].lower() == 'test.example.com' 
- A expressão a seguir corresponde a solicitações para um URL específico usando - endsWith:- request.headers['host'].lower().endsWith('.example.com')
- A expressão a seguir corresponde a solicitações para um URL específico usando - contains:- request.headers['host'].lower().contains('test.example.com')
- A expressão a seguir corresponde a solicitações para vários domínios usando - contains:- request.headers['host'].lower().contains('test.example.com') || request.headers['host'].lower().contains('test22.example.com')
- A expressão a seguir corresponde a solicitações de um domínio e seus subdomínios usando - matches:- request.headers['host'].matches('(?i:(sub\.)?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- AUcorrespondem à 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.4em 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 - Chromeno 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-Agentque contém- wordpress; corresponde a- User-Agent:WordPress/605.1.15,- User-Agent:wordPresse 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 - myValuepara o cabeçalho- user-id:- has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')
Permitir ou negar tráfego que contenha um valor de string de um comprimento 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-datamaior 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-lengthzero 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%2BValueou- 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 JA4 conhecida
- A expressão a seguir corresponde a solicitações que têm uma impressão digital JA4 igual a - t13d1516h2_8daaf6152771_b186095e22b6:- origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6' 
Permitir ou negar tráfego com base em uma lista de impressões digitais JA4
- A expressão a seguir corresponde a solicitações que têm uma impressão digital JA4 igual a qualquer uma das seguintes impressões digitais JA4: - t00d0000h0_000000000000_000000000000
- t13d1516h2_8daaf6152771_b186095e22b6
 - origin.tls_ja4_fingerprint == 't00d0000h0_000000000000_000000000000' || origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6' 
Regras pré-configuradas do WAF
As regras WAF pré-configuradas usam assinaturas estáticas pré-configuradas, expressões regulares ou ambas para corresponder ao corpo da solicitação HTTP, cabeçalhos de solicitação HTTP e parâmetros de consulta. As regras WAF pré-configuradas disponíveis são baseadas no conjunto de regras principais do OWASP versão 3.3. O Cloud Armor oferece várias regras WAF pré-configuradas predefinidas. Confira uma lista completa de regras WAF pré-configuradas na Visão geral das regras WAF pré-configuradas do 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>-<OWASP 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:
 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  | 
Exemplos de regras WAF pré-configuradas
- A expressão a seguir usa a regra WAF pré-configurada - xss-v33-stablepara mitigar ataques XSS:- evaluatePreconfiguredWaf('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- 941100e- 941110:- evaluatePreconfiguredWaf('xss-v33-stable', {'opt_out_rule_ids': ['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') && evaluatePreconfiguredWaf('sqli-v33-stable')
Outros operadores
| Expressões | Descrição | 
|---|---|
| evaluateThreatIntelligence(string)evaluateThreatIntelligence(string, LIST)evaluateThreatIntelligence(string, string, LIST) | Retorna "true" se o endereço IP de origem corresponder a qualquer um dos intervalos de IP na lista de IP especificada, a menos que seja explicitamente excluído com a lista de exclusão. O primeiro argumento é o nome do feed do Google Threat Intelligence, como  | 
| evaluateAddressGroup(string, string)evaluateAddressGroup(string, string, LIST)evaluateOrganizationAddressGroup(string, string)evaluateOrganizationAddressGroup(string, string, LIST) | Retorna "true" se o endereço IP de origem corresponder a qualquer um dos intervalos de IP no grupo de endereços especificado, a menos que seja explicitamente excluído com a lista de exclusão. O primeiro argumento é o nome do grupo de endereços. O segundo argumento determina de onde o endereço IP é extraído e pode ser  | 
| evaluateAdaptiveProtection(string) | Retorna "true" se a solicitação corresponder à assinatura de ataque produzida pela Proteção adaptativa. O argumento é o ID de um alerta específico gerado pela Proteção adaptativa ao detectar um ataque. | 
| evaluateAdaptiveProtectionAutoDeploy() | Retorna "true" se a solicitação for de um endereço IP de grande impacto que corresponda à assinatura de um ataque em andamento detectado pela Proteção adaptável. | 
Exemplos
- A expressão a seguir corresponde à solicitação recebida ao feed de inteligência contra ameaças do Google - iplist-known-malicious-ipspara proteção contra a lista conhecida de IPs maliciosos:- evaluateThreatIntelligence('iplist-known-malicious-ips')
- A expressão a seguir corresponde à solicitação recebida em relação ao feed de inteligência contra ameaças do Google - iplist-known-malicious-ipspara proteção contra a lista conhecida de IPs maliciosos, exceto os IPs em- 104.135.0.0/16:- evaluateThreatIntelligence('iplist-known-malicious-ips', ['104.135.0.0/16'])
- A expressão a seguir corresponde ao cabeçalho de solicitação personalizado para IP do usuário com o grupo de endereços chamado - my-own-list-of-bad-ips:- evaluateAddressGroup('my-own-list-of-bad-ips', origin.user_ip)
A seguir
- Configurar políticas de segurança do Cloud Armor
- Ajustar regras WAF pré-configuradas do Cloud Armor
- Resolver problemas do Cloud Armor
- Cotas e limites