Crea e visualizza le regole delle policy di sicurezza di Cloud Armor

Ogni regola delle policy di sicurezza di Google Cloud Armor ha una priorità, una condizione di corrispondenza e un'azione. Cloud Armor esegue l'azione della regola con la priorità più alta che corrisponde a una richiesta. Le regole con una priorità inferiore a quella della regola di corrispondenza con la priorità più alta non vengono valutate, anche se hanno le stesse condizioni di corrispondenza.

Ogni regola delle policy di sicurezza supporta due tipi di condizioni di corrispondenza:

  • Una condizione di corrispondenza di base contiene elenchi di indirizzi IP o elenchi di intervalli di indirizzi IP. Le condizioni di corrispondenza di base vengono definite utilizzando il flag --src-ip-ranges durante la creazione di una regola utilizzando Google Cloud CLI.
  • Una condizione di corrispondenza avanzata contiene un'espressione con un massimo di cinque sottoespressioni che possono corrispondere a una serie di attributi di una richiesta in entrata. Le condizioni di corrispondenza avanzate vengono definite utilizzando il flag --expression quando si crea una regola utilizzando Google Cloud CLI.

Questa pagina descrive come creare e visualizzare le regole delle policy di sicurezza e fornisce il riferimento per il linguaggio delle regole personalizzate di Cloud Armor che utilizzi per scrivere espressioni nelle condizioni di corrispondenza avanzate. Il linguaggio delle regole personalizzate di Cloud Armor è un sottoinsieme del Common Expression Language (CEL).

Le espressioni scritte nel linguaggio delle regole personalizzate di Cloud Armor richiedono due componenti:

  • L'attributo: i dati da esaminare
  • L'operazione: come utilizzare i dati

Ad esempio, la seguente espressione utilizza gli attributi origin.ip e 198.51.100.0/24 nell'operazione inIpRange. In questo caso, l'espressione restituisce true se origin.ip è compreso nell'intervallo di indirizzi IP 198.51.100.0/24.

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

Anche se l'espressione dell'esempio precedente corrisponde solo all'indirizzo IP client, quando utilizzi l'espressione di esempio in una regola delle policy di sicurezza di Cloud Armor, la regola è considerata una regola con condizioni di corrispondenza avanzate dal punto di vista della quota. Per maggiori informazioni, consulta Quote e limiti di Cloud Armor.

Crea regole delle policy di sicurezza

Segui i passaggi descritti in questa sezione per aggiungere regole a una policy di sicurezza di Cloud Armor.

Console

  1. Nella console Google Cloud , vai alla pagina Policy di Cloud Armor.

    Vai alle policy di Cloud Armor

  2. Fai clic sul nome della policy di sicurezza per aprire la pagina Dettagli policy, quindi fai clic sulla scheda Regole.

  3. Fai clic su Aggiungi regola.

  4. (Facoltativo) Inserisci una descrizione della regola.

  5. Seleziona la modalità:

    • Modalità di base: consente o nega il traffico in base agli indirizzi IP o agli intervalli IP.
    • Modalità avanzata: consente o nega il traffico in base alle espressioni della regola.
  6. Nel campo Corrispondenza, specifica le condizioni a cui si applica la regola:

    • Modalità base: inserisci da 1 a 10 intervalli di indirizzi IP a cui deve corrispondere la regola. Puoi aggiungere un massimo di 10 intervalli di indirizzi IP. Per i limiti, consulta Quote e limiti di Cloud Armor.

    • Modalità avanzata:

      • Generatore di condizioni di corrispondenza (anteprima): utilizza il generatore visivo per creare espressioni senza scrivere codice CEL non elaborato. Combina e raggruppa le condizioni e applica le trasformazioni stringa. Consulta Utilizza il generatore di condizioni di corrispondenza.
      • Editor di condizioni di corrispondenza: inserisci un'espressione da valutare rispetto alle richieste in entrata. Per saperne di più, consulta Operazioni e Attributi.
  7. Nell'elenco Azione, seleziona Consenti o Nega.

  8. Se stai configurando una regola Nega, seleziona un codice di risposta nell'elenco Codice di risposta.

  9. Per attivare la modalità di anteprima per la regola, seleziona Attiva.

  10. Nel campo Priorità, inserisci un numero intero compreso tra 0 e 2.147.483.646. Cloud Armor valuta le regole in ordine di priorità da 0 (valore più alto) a 2.147.483.647 (valore più basso). La regola predefinita ha una priorità di 2.147.483.647.

  11. Fai clic su Aggiungi.

gcloud

Utilizza il comando gcloud compute security-policies rules create PRIORITY. Sostituisci PRIORITY con la priorità della regola nella policy:

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

Ad esempio, il seguente comando aggiunge una regola con priorità 1000 per bloccare il traffico proveniente dagli intervalli di indirizzi IP 192.0.2.0/24 e 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"

Utilizza il flag --expression per specificare una condizione. Il seguente comando aggiunge una regola per consentire il traffico dall'indirizzo IP 1.2.3.4 che contiene la stringa example nell'intestazione 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'"

Il seguente comando aggiunge una regola per bloccare le richieste se il cookie della richiesta contiene un valore specifico:

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"

Il seguente comando aggiunge una regola per bloccare le richieste provenienti dalla regione AU:

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

Il seguente comando aggiunge una regola per bloccare le richieste provenienti dalla regione AU che non rientrano nell'intervallo IP specificato:

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"

Il seguente comando aggiunge una regola per bloccare le richieste con un URI che corrisponde a un'espressione regolare:

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

Il seguente comando aggiunge una regola per bloccare le richieste se il valore decodificato in Base64 dell'intestazione user-id contiene un valore specifico:

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"

Il seguente comando aggiunge una regola che utilizza un set di espressioni preconfigurate del set di regole di base (CRS) OWASP 4.22 per mitigare gli attacchi SQL injection (SQLi):

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

Utilizza il generatore di condizioni di corrispondenza

Il generatore di condizioni di corrispondenza è un'interfaccia visiva nella console Google Cloud che ti aiuta a creare espressioni di regole Cloud Armor complesse senza scrivere codice Common Expression Language (CEL). Anziché scrivere codice, puoi utilizzare l'interfaccia utente strutturata del builder per combinare condizioni e logica di gruppo, il che può aiutarti a evitare errori di sintassi e a visualizzare meglio la struttura delle regole. Il builder supporta elenchi semplici e logica nidificata fino a cinque livelli di espressioni. Utilizza questo strumento quando configuri le regole per proteggere i backend multi-cloud o i deployment ibridi, dove potrebbe essere necessario ispezionare attributi di richiesta specifici prima di instradare il traffico.

Funzionalità del generatore di condizioni di corrispondenza

Il generatore di condizioni di corrispondenza include le seguenti funzionalità:

  • Logica e nidificazione: combina più condizioni utilizzando gli operatori AND e OR. Il builder supporta il raggruppamento e l'nidificazione di un massimo di cinque espressioni.
  • Trasformazioni di stringhe: per gli attributi basati su stringhe (come request.path o request.headers), applica le trasformazioni per normalizzare i dati prima della valutazione. Le trasformazioni supportate includono:
    • Lettere minuscole e maiuscole
    • Decodifica Base64
    • Decodifica URL e Decodifica URL (Unicode)
    • Converti UTF-8 in Unicode
  • Analisi bidirezionale: passa dal generatore di condizioni di corrispondenza visivo all'editor di condizioni di corrispondenza di testo non elaborato. La UI analizza automaticamente il codice CEL non elaborato in blocchi visivi.
  • Supporto delle funzioni: il builder fornisce controlli UI per le espressioni basate su funzioni, come regole WAF preconfigurate, gruppi di indirizzi e Threat Intelligence.

Limitazioni

Il generatore di condizioni di corrispondenza è l'interfaccia predefinita per la creazione di regole avanzate. Se un'espressione contiene una logica non supportata (ad esempio macro sconosciute), il builder viene disattivato. In questi casi, utilizza il testo non elaborato nell'editor delle condizioni di corrispondenza per modificare la regola.

Inoltre, la disponibilità di determinate espressioni nel builder dipende dal livello Google Cloud Armor Enterprise del tuo progetto e dal tipo di policy di sicurezza.

Espressioni di esempio

Di seguito sono riportate alcune espressioni di esempio. Per saperne di più sulle operazioni e sugli attributi supportati, consulta Operazioni e Attributi.

Se la regola o l'espressione utilizza i codici paese o regione ISO 3166-1 alpha-2, Cloud Armor tratta ogni codice in modo indipendente. Le regole e le espressioni di Cloud Armor utilizzano questi codici per consentire o negare le richieste.

  • La seguente espressione corrisponde alle richieste provenienti dall'indirizzo IP 1.2.3.4 che contengono la stringa example nell'intestazione User-Agent:

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

    In alternativa, esegui la corrispondenza in base all'intervallo di indirizzi IP di un'intestazione di indirizzo IP client personalizzato utilizzando l'attributo origin.user_ip:

    inIpRange(origin.user_ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('example')
    
  • La seguente espressione corrisponde alle richieste che hanno un cookie con un valore specifico:

    has(request.headers['cookie']) && request.headers['cookie'].contains('cookie_name=cookie_value')
    
  • La seguente espressione corrisponde alle richieste provenienti dalla regione AU:

    origin.region_code == 'AU'
    
  • La seguente espressione corrisponde alle richieste provenienti dalla regione AU che non rientrano nell'intervallo IP specificato:

    origin.region_code == "AU" && !inIpRange(origin.ip, '1.2.3.0/24')
    
  • La seguente espressione corrisponde alle richieste con un percorso variabile numerato a un file specifico se l'URI corrisponde a un'espressione regolare:

    request.path.matches('/path/[0-9]+/target_file.html')
    
  • La seguente espressione corrisponde alle richieste se il valore decodificato in Base64 dell'intestazione user-id contiene un valore specifico:

    has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')
    
  • La seguente espressione utilizza un set di espressioni preconfigurato del set di regole OWASP CRS 4.22 per la corrispondenza con gli attacchi SQLi:

    evaluatePreconfiguredWaf('sqli-v422-stable')
    

Path traversal e normalizzazione

Normalizza i contenuti nelle regole basate sui percorsi per gestire le regole di attraversamento dei percorsi e di codifica e per creare regole generalizzate che evitino la codifica specifica per i contenuti o le lettere maiuscole.

Quando scrivi regole che utilizzano startsWith, endsWith o contains per la corrispondenza su request.path, utilizza lower e urlDecode per normalizzare il percorso prima della corrispondenza. In questo modo, si evitano bypass che utilizzano la codifica URL o variazioni di maiuscole e minuscole.

Ad esempio, per bloccare l'accesso alla directory /admin, utilizza la seguente espressione:

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

Questa regola blocca le richieste per /admin, /Admin, /a%64min e altre varianti.

Quando scrivi regole che utilizzano matches per trovare corrispondenze con request.path, tieni conto del carattere barra rovesciata (\) nell'espressione regolare.

Ad esempio, per bloccare l'accesso alla directory /admin, utilizza la seguente espressione per bloccare i bypass che utilizzano il carattere barra rovesciata (\):

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

Combina questa regola con urlDecode per gestire sia la codifica URL sia i bypass del carattere barra rovesciata (\):

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

Visualizza le regole delle policy di sicurezza

Le sezioni seguenti descrivono come elencare le regole configurate in una policy di sicurezza e visualizzare le regole WAF preconfigurate disponibili.

Elenca le regole in una policy di sicurezza

Segui i passaggi descritti in questa sezione per elencare le regole in una policy di sicurezza di Cloud Armor.

Console

  1. Nella console Google Cloud , vai alla pagina Policy di Cloud Armor.

    Vai alle policy di Cloud Armor

  2. Fai clic sul nome della policy di sicurezza specifica. La pagina Dettagli policy mostra le regole della policy nella scheda Regole.

gcloud

Utilizza il seguente comando gcloud per elencare tutte le regole di una policy di sicurezza:

gcloud compute security-policies describe NAME

Utilizza il seguente comando gcloud per elencare tutte le regole in una singola policy di sicurezza in una regione specificata insieme a una descrizione della policy:

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

Utilizza il seguente comando gcloud per descrivere una regola:

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

Ad esempio, il comando seguente descrive la regola con priorità 1000 nella policy di sicurezza my-policy:

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

Output:

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

Per saperne di più, consulta gcloud compute security-policies describe.

Elenca le regole preconfigurate disponibili

Oltre alle regole che configuri autonomamente, Cloud Armor fornisce regole preconfigurate che puoi utilizzare nelle tue policy di sicurezza. Puoi elencare le regole preconfigurate per visualizzare le regole e le firme di protezione delle applicazioni predefinite, ad esempio il set di regole di base OWASP (CRS), fornite da Cloud Armor. Queste regole contengono firme integrate che Cloud Armor valuta rispetto alle richieste in entrata. Aggiungi queste regole preconfigurate a regole nuove o esistenti utilizzando il linguaggio delle regole personalizzate. Ti consigliamo di utilizzare l'ultima versione delle regole CRS, se possibile.

gcloud

  1. Esegui il comando gcloud compute security-policies list-preconfigured-expression-sets:

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

    L'esempio seguente mostra la forma dell'output 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
    

    L'esempio seguente include un campione dell'output effettivo del comando. Tieni presente che l'output effettivo include tutte le regole elencate in Ottimizzazione delle regole WAF di 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
    

Operazioni

Il seguente riferimento descrive gli operatori che puoi utilizzare con gli attributi (rappresentati da x, y e k) per definire le espressioni delle regole.

Operazioni Espressioni Descrizione
Uguaglianza x == y Restituisce true se x è uguale a y.
Uguaglianza, valore letterale stringa x == "foo" Restituisce true se x è uguale al valore letterale stringa costante specificato.
Uguaglianza, valore letterale di stringa non elaborata x == R"fo'o" Restituisce true se x è uguale al valore letterale della stringa non elaborata specificata che non interpreta le sequenze di escape. I valori letterali stringa non elaborata sono utili per esprimere stringhe che devono utilizzare caratteri di sequenza di escape.
NOT logico !x Restituisce true se il valore booleano x è false oppure restituisce false se il valore booleano x è true.
Disuguaglianza x != y Restituisce true se x è diverso da y.
Concatenazione x + y Restituisce la stringa concatenata xy.
AND logico x && y Restituisce true se x e y sono entrambi true.
OR logico x || y Restituisce true se x, y o entrambi sono true.
Contiene la sottostringa x.contains(y) Restituisce true se la stringa x contiene la sottostringa y.
Inizia con la sottostringa x.startsWith(y) Restituisce true se la stringa x inizia con la sottostringa y.
Termina con la sottostringa x.endsWith(y) Restituisce true se la stringa x termina con la sottostringa y.
Corrispondenza mediante espressione regolare x.matches(y) Restituisce true se la stringa x corrisponde parzialmente al pattern y RE2 specificato. Il pattern RE2 viene compilato utilizzando l'opzione RE2::Latin1 che disabilita le funzionalità Unicode.
Indirizzo IP compreso nell'intervallo inIpRange(x, y) Restituisce true se l'indirizzo IP x è contenuto nell'intervallo IP y.
Minuscolo x.lower() Restituisce il valore in minuscolo della stringa x.
Maiuscolo x.upper() Restituisce il valore in maiuscolo della stringa x.
Valore decodificato Base64 x.base64Decode() Restituisce il valore con codifica Base64 di x; il trattino basso (_) e il trattino (-) vengono prima sostituiti rispettivamente con la barra (/) e il segno più (+). Restituisce "" (stringa vuota) se x non è un valore base64 valido.
Valore della mappa delle chiavi m['k'] Restituisce il valore della chiave k nella mappa stringa-stringa m se k è disponibile; altrimenti, restituisce un errore. L'approccio consigliato è verificare prima la disponibilità utilizzando "has(m['k'])==true".
Controlla la disponibilità delle chiavi in una mappa has(m['k']) Restituisce true se la chiave k è disponibile nella mappa m.
Converti in numero intero int(x) Converte il risultato della stringa di x in un tipo int. Può quindi essere utilizzato per eseguire un confronto tra numeri interi utilizzando operatori aritmetici standard come > e <=. Questa operazione funziona solo per i valori che devono essere numeri interi.
Lunghezza size(x) Restituisce la lunghezza della stringa x.
Decodifica URL x.urlDecode() Restituisce il valore decodificato dall'URL di x; le sequenze di caratteri nel formato %## vengono sostituite con gli equivalenti non ASCII e + viene sostituito con uno spazio. Le codifiche non valide vengono restituite così come sono.
Decodifica URL (Unicode) x.urlDecodeUni() Restituisce il valore decodificato dall'URL di x; oltre a urlDecode(), gestisce anche le sequenze di caratteri Unicode nel formato %u###. Le codifiche non valide vengono restituite così come sono.
Converti utf8 in Unicode x.utf8ToUnicode() Restituisce la rappresentazione Unicode in minuscolo di un valore x codificato in UTF-8.
Esistente m.exists(k, expr) Restituisce true se almeno una voce nella mappa m soddisfa expr, dove k rappresenta la chiave di ogni voce della mappa.
Ne esiste uno m.exists_one(k, expr) Restituisce true se esattamente una voce nella mappa m soddisfa expr, dove k rappresenta la chiave di ogni voce della mappa.
Tutti m.all(k, expr) Restituisce true se tutte le voci della mappa m soddisfano expr, dove k rappresenta la chiave di ogni voce della mappa.
Filtro m.filter(k, expr) Restituisce una mappa contenente solo le voci della mappa m in cui la voce soddisfa expr, dove k rappresenta la chiave di ogni voce della mappa.
Mappa m.map(k, expr) Restituisce un elenco contenente il risultato della valutazione di expr per ogni chiave nella mappa m, dove k rappresenta la chiave di ogni voce della mappa.

Attributi

Gli attributi rappresentano le informazioni di una richiesta in entrata, ad esempio l'indirizzo IP client o il percorso dell'URL richiesto.

Campo Tipo Descrizione del campo
origin.ip string L'indirizzo IP del client che ha avviato la richiesta.
origin.user_ip string L'indirizzo IP del client di origine, incluso in HTTP-HEADER da un proxy upstream. Prima di utilizzare questo attributo, devi configurare l'opzione userIpRequestHeaders[] nel campo advancedOptionsConfig della policy di sicurezza in modo che corrisponda a un'origine come True-Client-IP, X-Forwarded-For o X-Real-IP. Per saperne di più, consulta Panoramica degli indirizzi IP utente.

Se non configuri l'opzione userIpRequestHeaders[], se l'intestazione configurata contiene valori di indirizzo IP non validi o se l'intestazione configurata non è presente, origin.user_ip viene impostato su origin.ip per impostazione predefinita. Per saperne di più, consulta il riferimento alla risorsa securityPolicy.

origin.tls_ja4_fingerprint string Impronta TLS/SSL JA4 se il client si connette utilizzando HTTPS, HTTP/2 o HTTP/3. Se non disponibile, viene restituita una stringa vuota.
origin.tls_ja3_fingerprint string Impronta JA3 TLS/SSL se il client si connette utilizzando HTTPS, HTTP/2 o HTTP/3. Se non disponibile, viene restituita una stringa vuota.
request.headers mappa Una mappa stringa-stringa delle intestazioni delle richieste HTTP. Se un'intestazione ha più valori, il valore corrispondente in questa mappa è una singola stringa che contiene tutti i valori, separati da virgole. Le chiavi in questa mappa contengono solo lettere minuscole. I bilanciatori del carico delle applicazioni esterni ispezionano tutte le intestazioni accettate e si applicano le stesse limitazioni delle intestazioni.

Usa has() per verificare la disponibilità, ad esempio has(request.headers['header-key']) && request.headers['header-key'] != 'header-value'.

Puoi eseguire l'iterazione sulla mappa per controllare sia le chiavi che i valori. Tuttavia, puoi utilizzare gli operatori di iterazione della mappa (exists(), exists_one(), all(), filter() e map()) su request.headers solo in combinazione con request.body o request.params nella stessa espressione, ad esempio request.body && request.headers.exists(k, k.lower().startsWith('header-prefix')).

request.body string Rappresenta il corpo della richiesta come stringa non elaborata. Può rappresentare i dati di qualsiasi Content-Type. Archivia i contenuti come stringa senza alcuna analisi automatica.
request.params mappa Una mappa di coppie chiave-valore che vengono aggiunte all'URL o incluse nel corpo delle richieste.
Richiesta URI: name1=value1&name2=value2
Corpo della richiesta JSON con Content-Type: application/json:
{ "username": "johndoe", "email": "johndoe@example.com" }
Corpo della richiesta POST GraphQL con Content-Type: application/graphql:
{ Username: "exampleUser", query: "/* other fields */" }
Corpo della richiesta POST del modulo con Content-Type: application/x-www-form-urlencoded:
"username=exampleUser&email=johndoe%40example.com"
request.method string Il metodo di richiesta HTTP.
request.path string Il percorso URL HTTP richiesto. Quando scrivi regole che corrispondono a request.path, ti consigliamo di normalizzare il percorso per facilitare la sintassi di corrispondenza in caso di codifica dell'URL, variazioni di maiuscole e minuscole o barre rovesciate. Per ulteriori informazioni ed esempi, consulta Attraversamento e normalizzazione dei percorsi.
request.scheme string Lo schema URL HTTP, ad esempio http o https. I valori di questo attributo sono tutti in minuscolo.
request.query string La query URL HTTP nel formato name1=value&name2=value2, come appare nella prima riga della richiesta HTTP. Non viene eseguita alcuna decodifica.
origin.region_code string Il codice paese Unicode associato all'IP client, ad esempio US. Se crei una regola o un'espressione che utilizza i codici paese o regione ISO 3166-1 alpha 2, Cloud Armor tratta ogni codice in modo indipendente. Le regole e le espressioni di Cloud Armor utilizzano esplicitamente questi codici regione per consentire o negare le richieste.
origin.asn intero Il numero di sistema autonomo (ASN) associato all'indirizzo IP client. L'ASN univoco a livello globale viene determinato in base all'operatore di rete che supporta i prefissi IP che contengono l'indirizzo IP client.

Attributi reCAPTCHA

Questa sezione elenca gli attributi applicabili solo ai token reCAPTCHA o ai cookie di esenzione. Un'espressione secondaria basata su questi attributi restituisce false se il token reCAPTCHA o il cookie di esenzione da valutare non è disponibile o non è valido per uno dei seguenti motivi:

  • Il token non è in un formato corretto e non può essere decodificato.
  • Il token contiene attributi non validi. Ad esempio, il token è stato generato utilizzando una chiave reCAPTCHA che non corrisponde alle chiavi reCAPTCHA associate alla regola.
  • Il token è scaduto.
Campo Tipo Descrizione del campo
token.recaptcha_exemption.valid bool La presenza di un cookie di esenzione reCAPTCHA valido.

Attributi token di azione

Campo Tipo Descrizione del campo
token.recaptcha_action.score float Il punteggio di un token di azione reCAPTCHA. Un punteggio valido va da 0.0 a 1.0, dove 0.0 indica un utente molto probabilmente illegittimo e 1.0 indica un utente molto probabilmente legittimo.
token.recaptcha_action.captcha_status string Lo stato del captcha di un token di azione reCAPTCHA. Uno stato valido è NONE, PASS o FAIL, dove NONE si riferisce a quando non sono coinvolte sfide durante il test reCAPTCHA, in modo che il campo CAPTCHA non sia presente nel token di azione.
token.recaptcha_action.action string Il nome dell'azione (fino a 100 caratteri) di un token di azione reCAPTCHA. Vedi Nomi delle azioni.
token.recaptcha_action.valid bool La presenza di un token di azione reCAPTCHA valido.

Attributi del token di sessione

Campo Tipo Descrizione del campo
token.recaptcha_session.score float Il punteggio di un token di sessione reCAPTCHA. Un punteggio valido va da 0.0 a 1.0, dove 0.0 indica un utente molto probabilmente illegittimo e 1.0 indica un utente molto probabilmente legittimo.
token.recaptcha_session.valid bool La presenza di un token di sessione reCAPTCHA valido.

Espressioni di esempio

Per ciascuna di queste espressioni, l'azione intrapresa dipende dal fatto che l'espressione sia inclusa in una regola di negazione o in una regola di autorizzazione.

Consenti o nega l'accesso in base a un intervallo di indirizzi IP in IPv4 o IPv6

  • La seguente espressione corrisponde alle richieste provenienti dall'intervallo di indirizzi IP 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24')
    
  • La seguente espressione corrisponde alle richieste provenienti dall'intervallo di indirizzi IP 2001:db8::/32:

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

Consenti o nega l'accesso in base a un intervallo di indirizzi IP client personalizzato dietro un proxy upstream

Se hai configurato l'operatore origin.user_ip, puoi eseguire la corrispondenza in base ai valori dell'intestazione specificati nel campo advancedOptionsConfig.userIpRequestHeaders[].

  • La seguente espressione corrisponde alle richieste provenienti dall'intervallo di indirizzi IP 192.0.2.0/24:

    inIpRange(origin.user_ip, '192.0.2.0/24')
    
  • La seguente espressione corrisponde alle richieste provenienti dall'intervallo di indirizzi IP 2001:db8::/32:

    inIpRange(origin.user_ip, '2001:db8::/32')
    
  • La seguente espressione corrisponde alle richieste che hanno un cookie contenente 80=BLAH:

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

Consenti o nega il traffico con un'intestazione referer non vuota

  • La seguente espressione corrisponde alle richieste con un'intestazione referer non vuota:

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

Consenti o nega il traffico in base all'intestazione host

Puoi consentire o negare il traffico in base al valore dell'intestazione Host nella richiesta.

  • La seguente espressione corrisponde alle richieste a un URL specifico utilizzando ==:

    request.headers['host'].lower() == 'test.example.com'
    
  • La seguente espressione corrisponde alle richieste a un URL specifico utilizzando endsWith:

    request.headers['host'].lower().endsWith('.example.com')
    
  • La seguente espressione corrisponde alle richieste a un URL specifico utilizzando contains:

    request.headers['host'].lower().contains('test.example.com')
    
  • La seguente espressione corrisponde alle richieste a più domini che utilizzano contains:

    request.headers['host'].lower().contains('test.example.com') || request.headers['host'].lower().contains('test22.example.com')
    
  • La seguente espressione corrisponde alle richieste per un dominio e i relativi sottodomini utilizzando matches:

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

Consenti o nega il traffico da una regione specifica

Se la tua applicazione web non è disponibile nella regione AU, tutte le richieste provenienti da quella regione devono essere bloccate.

  • In una regola di negazione, utilizza la seguente espressione, che corrisponde alle richieste provenienti dalla regione AU:

    origin.region_code == 'AU'
    

In alternativa, se la tua applicazione web è disponibile solo nella regione AU, le richieste provenienti da tutte le altre regioni devono essere bloccate.

  • In una regola di negazione, utilizza la seguente espressione, che corrisponde alle richieste provenienti da tutte le regioni diverse dalla regione AU:

    origin.region_code != 'AU'
    

I codici regione si basano sui codici ISO 3166-1 alpha-2. In alcuni casi, una regione corrisponde a un paese, ma non è sempre così. Ad esempio, il codice US include tutti gli stati degli Stati Uniti, un distretto e sei aree periferiche.

Consenti o nega il traffico da un ASN specifico

Se la tua applicazione web deve essere bloccata per i clienti serviti da un operatore di rete specifico, puoi utilizzare il numero ASN dell'operatore di rete per il blocco.

  • In una regola di negazione, utilizza la seguente espressione, che corrisponde alle richieste provenienti da un ASN specifico:

    origin.asn == 123
    

In alternativa, se la tua applicazione web deve essere disponibile solo per i clienti di un operatore di rete specifico, le richieste di tutti gli altri operatori di rete devono essere bloccate.

  • In una regola di negazione, utilizza la seguente espressione, che corrisponde a tutti gli altri operatori di rete diversi da quello che ti interessa consentire:

    origin.asn != 123
    

Più espressioni

Per includere più condizioni in una singola regola, combina più sottoespressioni.

  • Nel seguente esempio, le richieste provenienti da 1.2.3.0/24 (ad esempio i tuoi alpha tester) nella regione AU corrispondono alla seguente espressione:

    origin.region_code == "AU" && inIpRange(origin.ip, '1.2.3.0/24')
    
  • La seguente espressione corrisponde alle richieste provenienti da 1.2.3.4 in cui uno user agent contiene la stringa WordPress:

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

Consenti o nega il traffico per un URI della richiesta che corrisponde a un'espressione regolare

  • La seguente espressione corrisponde alle richieste che contengono la stringa /example_path/ nell'URI:

    request.path.matches('/example_path/')
    
  • La seguente espressione corrisponde alle richieste che contengono Chrome nel campo dell'intestazione User-Agent:

    request.headers['user-agent'].matches('Chrome')
    
  • La seguente espressione mostra la corrispondenza senza distinzione tra maiuscole e minuscole per l'intestazione User-Agent contenente wordpress; corrisponde a User-Agent:WordPress/605.1.15, User-Agent:wordPress e altre varianti di wordpress:

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

Consenti o nega il traffico che contiene un valore decodificato in Base64 specifico

  • La seguente espressione corrisponde alle richieste con un valore decodificato in base64 di myValue per l'intestazione user-id:

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

Consenti o nega il traffico che contiene un valore stringa di una lunghezza specifica

  • La seguente espressione corrisponde alle richieste con una lunghezza dell'URL superiore a 10 caratteri:

    size(request.path) > 10
    
  • La seguente espressione corrisponde alle richieste con un'intestazione di lunghezza x-data maggiore o uguale a 1024 caratteri:

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

Consenti o nega il traffico con content-length zero nel corpo HTTP

  • La seguente espressione corrisponde alle richieste che hanno uno zero content-length nel corpo HTTP:

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

Consenti o nega il traffico che contiene un valore codificato come URL specifico

  • La seguente espressione corrisponde alle richieste che hanno un valore del cookie contenente %3c:

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

Consenti o nega il traffico che contiene un valore codificato URL specifico di una stringa Unicode

  • La seguente espressione corrisponde alle richieste con un valore del cookie uguale a Match%2BValue o Match%u002BValue:

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

Consenti o nega il traffico che contiene una stringa Unicode specifica di un testo UTF-8

  • La seguente espressione corrisponde alle richieste con un valore del cookie uguale a ¬:

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

Consenti o nega il traffico in base a una fingerprint JA4 nota

  • La seguente espressione corrisponde alle richieste con una fingerprint JA4 uguale a t13d1516h2_8daaf6152771_b186095e22b6:

    origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
    

Consenti o nega il traffico in base a un elenco di fingerprint JA4

  • La seguente espressione corrisponde alle richieste con una fingerprint JA4 uguale a una delle seguenti fingerprint JA4:

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

Consenti o nega il traffico in base ai contenuti del corpo della richiesta

  • La seguente espressione corrisponde alle richieste POST che contengono malicious-value nel corpo della richiesta:

    request.method == 'POST' && request.body.contains('malicious-value')
    
  • La seguente espressione corrisponde alle richieste che iniziano con <!DOCTYPE html>:

    request.body.startsWith('<!DOCTYPE html>')
    
  • La seguente espressione corrisponde alle richieste in cui il corpo corrisponde all'espressione regolare \w+@\w+.com:

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

Consenti o nega il traffico in base ai parametri della richiesta

  • La seguente espressione corrisponde alle richieste che non contengono un parametro denominato category:

    !has(request.params.category)
    
  • La seguente espressione corrisponde alle richieste in cui il parametro category è electronics:

    request.params.category == 'electronics'
    
  • La seguente espressione corrisponde alle richieste in cui tutti i valori dei parametri non sono vuoti:

    request.params.all(k, request.params[k] != '')
    
  • La seguente espressione corrisponde alle richieste in cui un parametro contiene la stringa admin:

    request.params.exists(k, request.params[k].contains('admin'))
    
  • La seguente espressione corrisponde alle richieste in cui esattamente un nome di parametro contiene admin:

    request.params.exists_one(k, k.contains('admin'))
    
  • La seguente espressione corrisponde alle richieste in cui almeno un nome di parametro contiene id:

    size(request.params.filter(k, k.contains('id'))) > 0
    
  • La seguente espressione corrisponde alle richieste in cui i valori dei parametri includono la stringa admin:

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

Consenti o nega il traffico in base ai dati strutturati nel corpo della richiesta

  • La seguente espressione corrisponde alle richieste in cui il campo password nel corpo di una richiesta JSON contiene 123:

    has(request.params.password) && request.params.password.contains('123')
    
  • La seguente espressione corrisponde alle richieste in cui il campo city nei dati del modulo è NewYork:

    has(request.params.city) && request.params.city == 'NewYork'
    
  • La seguente espressione corrisponde alle richieste in cui il campo newsletter nidificato è true:

    has(request.params.preferences) && has(request.params.preferences.newsletter) && request.params.preferences.newsletter == true
    
  • La seguente espressione corrisponde alle richieste in cui il campo name del primo elemento nell'array friends è johndoe:

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

Regole WAF preconfigurate

Le regole WAF preconfigurate utilizzano firme statiche o espressioni regolari preconfigurate, o entrambe, per trovare corrispondenze nel corpo della richiesta HTTP, nelle intestazioni delle richieste HTTP e nei parametri di query. Le regole WAF preconfigurate disponibili si basano sul set di regole di base (CRS) OWASP 4.22. Cloud Armor fornisce diverse regole WAF preconfigurate predefinite. Per un elenco completo delle regole WAF preconfigurate, consulta la panoramica delle regole WAF preconfigurate di Cloud Armor.

Per elencare tutte le regole WAF preconfigurate disponibili, consulta Elenca le regole WAF preconfigurate disponibili.

Per saperne di più sulle regole WAF preconfigurate, consulta il caso d'uso Mitiga gli attacchi a livello di applicazione utilizzando le regole WAF preconfigurate.

Nomi delle regole WAF preconfigurate

I nomi delle regole WAF preconfigurate hanno il formato <attack category>-<OWASP CRS version>-<version field>. La categoria di attacco specifica il tipo di attacchi da cui vuoi proteggerti, come xss (cross-site scripting) o sqli (SQL injection).

I campi Version supportati sono stable e canary. Le aggiunte e le modifiche alle regole vengono rilasciate prima nella versione canary. Quando le aggiunte e le modifiche sono considerate sicure e stabili, vengono promosse alla versione stable.

ID membri delle regole WAF preconfigurate

Una regola WAF preconfigurata contiene diverse espressioni, ognuna con la propria firma. Ad esempio, la regola WAF preconfigurata xss-v422-stable include un'espressione denominata owasp-crs-v042200-id941100-xss, che corrisponde all'ID regola id941100 per la versione 4.22. Puoi utilizzare le firme per escludere espressioni specifiche, il che è utile se una determinata espressione attiva costantemente un falso positivo. Per saperne di più, consulta le informazioni sulla risoluzione dei problemi relativi ai falsi positivi.

Per informazioni sul set di regole di base e sull'ottimizzazione a diversi livelli di sensibilità, vedi Ottimizzazione delle regole WAF di Cloud Armor.

Operatore per le regole WAF preconfigurate

Espressioni Descrizione
evaluatePreconfiguredWaf(string, MAP<string, dyn>) Restituisce true se una delle firme WAF all'interno del set di regole WAF specificato restituisce true. Il primo argomento è il nome del set di regole WAF, ad esempio xss-v422-stable. Il secondo argomento (facoltativo) è una mappa in cui la chiave è una stringa e il valore è tipizzato in modo dinamico a seconda della chiave. Lo scopo di questo argomento è ottimizzare le firme WAF valutate. Le chiavi accettate includono le seguenti:
  • sensitivity: corrisponde al livello di paranoia del set di regole di base OWASP, che ha 4 livelli, da 1 a 4. Il suo valore è un numero intero con un intervallo valido da 0 a 4. Tieni presente che 0 è riservato come valore valido se utilizzato in combinazione con opt_in_rule_ids (descritto in un secondo momento). Quando specifichi una sensibilità pari a x (x >= 1), vengono valutate tutte le firme WAF associate con un valore di sensibilità compreso tra 1 e x. Se omesso, viene utilizzato 4 come valore di sensibilità.
  • opt_out_rule_ids: firme WAF (rappresentate dagli ID regola) da escludere dalla valutazione, dove il set di base è determinato dal valore di sensibilità. Il suo valore è un elenco di stringhe. Il numero massimo di ID regola consentiti è 128.
  • opt_in_rule_ids: firme WAF (rappresentate dagli ID regola) da attivare per la valutazione, dove il set di base è vuoto. Il suo valore è un elenco di stringhe. Il numero massimo di ID regola consentiti è 128. Quando lo utilizzi, devi specificare un sensitivity di 0.

Le chiavi opt_out_rule_ids e opt_in_rule_ids si escludono a vicenda. Puoi scegliere di utilizzare opt_in_rule_ids se vuoi esaminare e attivare manualmente le nuove firme WAF che vengono aggiunte in un secondo momento a un set di regole esistente.

evaluatePreconfiguredWaf(string, LIST)

Restituisce true se una delle espressioni all'interno della regola WAF preconfigurata specificata restituisce true.

Il primo argomento è il nome della regola WAF preconfigurata, ad esempio xss-stable. Il secondo argomento (facoltativo) è un elenco di stringhe separate da virgole di ID da escludere dalla valutazione. L'elenco di esclusione è utile quando un determinato membro della regola WAF preconfigurata attiva un falso positivo.

Esempi di regole WAF preconfigurate

  • La seguente espressione utilizza la regola WAF preconfigurata xss-v422-stable per mitigare gli attacchi XSS:

    evaluatePreconfiguredWaf('xss-v422-stable')
    
  • La seguente espressione utilizza tutte le espressioni della regola WAF preconfigurata xss-v422-stable, tranne gli ID membro 941100 e 941110:

    evaluatePreconfiguredWaf('xss-v422-stable', {'opt_out_rule_ids': ['owasp-crs-v042200-id941100-xss',
    'owasp-crs-v042200-id941110-xss']})
    
  • La seguente espressione utilizza una regola WAF preconfigurata per mitigare gli attacchi SQLi dall'intervallo di indirizzi IP 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredWaf('sqli-v422-stable')
    
  • La seguente espressione utilizza la regola WAF preconfigurata xss-v422-stable per mitigare gli attacchi XSS per le richieste a example.com, esclusi i percorsi che iniziano con /login/api/:

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

Regole gestite

Le regole gestite di Google Cloud Armor proteggono le tue app web e i tuoi endpoint API con firme di sicurezza aggiornate automaticamente. Le regole gestite sono fornite da Thales Imperva e si integrano direttamente in Cloud Armor, semplificando le operazioni di sicurezza. Le regole gestite eliminano la necessità di aggiornamenti manuali delle firme e riducono la deviazione della configurazione, consentendo al tuo team di sicurezza di concentrarsi sullo sviluppo e sulle operazioni.

Operatore per le regole gestite

Espressioni Descrizione
evaluateManagedRules(string, MAP<string, dyn>) Restituisce true se una delle firme all'interno delle regole gestite specificate restituisce true. Il primo argomento è il nome completo della categoria, ad esempio google:xss:stable o google:sqli:canary. Il secondo argomento (facoltativo) è una mappa in cui la chiave è una stringa e il valore è tipizzato in modo dinamico a seconda della chiave. Le chiavi accettate includono le seguenti:
  • opt_in_rule_ids: un elenco di ID regola del set di regole corrispondente che sono le uniche regole valutate. Ad esempio, evaluateManagedRules('google:xss:canary', {'opt_in_rule_ids': ['google-xss-8057544707029182464']}).
  • opt_out_rule_ids: un elenco di ID regola del set di regole corrispondente che sono esclusi dalla valutazione. Ad esempio, evaluateManagedRules('google:xss:canary', {'opt_out_rule_ids': ['google-xss-8057544707029182464']}).

Esempi di regole gestite

  • La seguente espressione utilizza le regole gestite per SQL injection (sqli) stabili per contribuire a prevenire gli attacchi SQLi:

    evaluateManagedRules('google:sqli:stable')
    
  • La seguente espressione utilizza le regole gestite xss stabili solo se la richiesta ha l'host example.com:

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

Altri operatori

Espressioni Descrizione
evaluateThreatIntelligence(string)
evaluateThreatIntelligence(string, LIST)
evaluateThreatIntelligence(string, string, LIST)

Restituisce true se l'indirizzo IP client corrisponde a uno degli intervalli IP nell'elenco IP specificato, a meno che non sia escluso esplicitamente con l'elenco di esclusione.

Il primo argomento è il nome del feed Google Threat Intelligence, ad esempio iplist-known-malicious-ips. Se il secondo argomento è una stringa (facoltativa), determina da dove viene estratto l'indirizzo IP e può essere origin.ip, origin.user_ip o un nome di intestazione specifico. Se il secondo o il terzo argomento (facoltativo) è un elenco di stringhe separate da virgole, in cui ogni stringa è un indirizzo IP o un intervallo CIDR, questo verrà escluso dalla valutazione. L'elenco di esclusione è utile quando un feed contiene un indirizzo IP che genera un falso positivo.

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

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

Restituisce true se l'indirizzo IP client corrisponde a uno degli intervalli IP nel gruppo di indirizzi specificato, a meno che non sia escluso esplicitamente con l'elenco di esclusione.

Il primo argomento è il nome del gruppo di indirizzi. Il secondo argomento determina da dove viene estratto l'indirizzo IP e può essere origin.ip, origin.user_ip o un nome di intestazione specifico. Il terzo argomento (facoltativo) è un elenco separato da virgole di stringhe, in cui ogni stringa è un indirizzo IP o un intervallo CIDR che verrà escluso dalla valutazione. L'elenco di esclusione è utile quando un gruppo di indirizzi contiene alcuni indirizzi IP che attivano un falso positivo.

evaluateAdaptiveProtection(string)

Restituisce true se la richiesta corrisponde alla firma dell'attacco prodotta da Google Cloud Armor Adaptive Protection.

L'argomento è l'ID di un avviso specifico generato da Adaptive Protection al rilevamento di un attacco.

evaluateAdaptiveProtectionAutoDeploy()

Restituisce true se la richiesta proviene da un indirizzo IP heavy hitter che corrisponde alla firma di attacco di un attacco in corso rilevato da Adaptive Protection.

Esempi

  • La seguente espressione confronta la richiesta in entrata con il feed iplist-known-malicious-ips di Google Threat Intelligence per la protezione dall'elenco noto di IP dannosi:

    evaluateThreatIntelligence('iplist-known-malicious-ips')
    
  • La seguente espressione confronta la richiesta in entrata con il feed iplist-known-malicious-ips di Google Threat Intelligence per la protezione dall'elenco noto di IP dannosi, ad eccezione degli IP in 203.0.113.0/24:

    evaluateThreatIntelligence('iplist-known-malicious-ips', ['203.0.113.0/24'])
    
  • La seguente espressione confronta l'intestazione della richiesta personalizzata per l'IP utente con il gruppo di indirizzi denominato my-own-list-of-bad-ips:

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

Passaggi successivi