Configurazione degli attributi del linguaggio delle regole personalizzate

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

Ogni regola del criterio 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 con 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 durante la creazione di una regola mediante Google Cloud CLI.

Questa pagina illustra le condizioni di corrispondenza avanzate e il linguaggio delle regole personalizzate di Google Cloud Armor che utilizzi per scrivere espressioni nelle condizioni di corrispondenza avanzate delle regole dei criteri di sicurezza. Il linguaggio delle regole personalizzate di Google Cloud Armor è un sottoinsieme del Common Expression Language (CEL). Le espressioni scritte nel linguaggio delle regole personalizzate di Google Cloud Armor richiedono due componenti:

  • L'attributo: i dati da ispezionare.
  • L'operazione: come utilizzare i dati

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

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

Anche se l'espressione di esempio precedente corrisponde solo all'indirizzo IP di origine, quando utilizzi l'espressione di esempio in una regola del criterio di sicurezza di Google Cloud Armor, la regola viene considerata come una regola con condizioni di corrispondenza avanzate dal punto di vista delle quote. Per ulteriori informazioni, consulta Quote e limiti di Google Cloud Armor.

Attributi

Gli attributi rappresentano informazioni di una richiesta in entrata, come l'indirizzo IP di origine o il percorso dell'URL richiesto.

Campo Tipo Descrizione del campo
origin.ip string L'indirizzo IP di origine della 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 del criterio di sicurezza in modo che corrisponda a un'origine come True-Client-IP, X-Forwarded-For o X-Real-IP.

Se non configuri l'opzione userIpRequestHeaders[], se l'intestazione configurata contiene valori di indirizzi IP non validi o se l'intestazione configurata non è presente, il valore predefinito di origin.user_ip sarà origin.ip. Per maggiori informazioni, consulta il riferimento delle risorse securityPolicy.

origin.tls_ja3_fingerprint string Fingerprint TLS/SSL JA3 se il client si connette tramite 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 contiene più valori, il valore in questa mappa sarà una stringa separata da virgole di tutti i valori dell'intestazione. Le chiavi in questa mappa sono tutte minuscole. Tutte le intestazioni accettate da Application Load Balancer esterni vengono ispezionate e si applicano le stesse limitazioni di intestazione.
request.method string Il metodo di richiesta HTTP, ad esempio GET o POST.
request.path string Il percorso URL HTTP richiesto.
request.scheme string Lo schema URL HTTP, ad esempio http o https. I valori di questo attributo sono tutti minuscoli.
request.query string La query URL HTTP nel formato name1=value&name2=value2, così come viene visualizzato nella prima riga della richiesta HTTP. Non viene eseguita alcuna decodifica.
origin.region_code string Il codice paese Unicode associato all'IP di origine, ad esempio US. Se stai creando una regola o un'espressione che utilizza i codici paese o regione ISO 3166-1 alpha 2, Google Cloud Armor tratta ciascun codice in modo indipendente. Le regole e le espressioni di Google Cloud Armor utilizzano esplicitamente questi codici regione per consentire o negare le richieste.

Per ulteriori informazioni, consulta unicode_region_subtag in Unicode Technical Standard.

origin.asn integer Il numero di sistema autonomo (ASN) associato all'indirizzo IP di origine. L'ASN univoco globale è determinato in base all'operatore di rete che supporta i prefissi degli indirizzi IP che contengono l'indirizzo IP di origine.

Attributi di reCAPTCHA Enterprise

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

  • Il token non è valido 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 per 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 corrisponde molto probabilmente a un utente illegittimo e 1.0 molto probabilmente un utente legittimo.
token.recaptcha_action.captcha_status string Lo stato del captcha da un token di azione reCAPTCHA. Uno stato valido è NONE, PASS o FAIL, dove NONE si riferisce a quando non sono previste verifiche durante test reCAPTCHA, ad esempio il campo captcha non è presente nel token di azione.
token.recaptcha_action.action string Il nome dell'azione (fino a 100 caratteri) da un token di azione reCAPTCHA. Consulta la sezione Nomi azioni.
token.recaptcha_action.valid bool La presenza di un token di azione reCAPTCHA valido.

Attributi per 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 corrisponde molto probabilmente a un utente illegittimo e 1.0 molto probabilmente un utente legittimo.
token.recaptcha_session.valid bool La presenza di un token di sessione reCAPTCHA valido.

Suite operativa

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

Espressioni Descrizione
x == "foo" Restituisce true se x è uguale al valore letterale stringa costante specificato.
x == R"fo'o" Restituisce true se x è uguale al valore letterale della stringa non elaborata specificato che non interpreta le sequenze di escape. I valori letterali stringa non elaborata sono comodi per esprimere le stringhe che a loro volta devono utilizzare caratteri di sequenza di escape.
x == y Restituisce true se x è uguale a y.
x != y Restituisce true se x è diverso da y.
x + y Restituisce la stringa concatenata xy.
x && y Restituisce true se x e y sono entrambi vere.
x || y Restituisce true se x, y o entrambi sono veri.
!x Restituisce true se il valore booleano x è falso oppure restituisce false se il valore booleano x è vero.
x.contains(y) Restituisce true se la stringa x contiene la sottostringa y.
x.startsWith(y) Restituisce true se la stringa x inizia con la sottostringa y.
x.endsWith(y) Restituisce true se la stringa x termina con la sottostringa y.
x.matches(y) Restituisce true se la stringa x corrisponde parzialmente al pattern RE2 y specificato. Il pattern RE2 viene compilato utilizzando l'opzione RE2::Latin1 che disabilita le funzionalità Unicode.
inIpRange(x, y) Restituisce true se l'indirizzo IP x è compreso nell'intervallo IP y. Le subnet mask per gli indirizzi IPv6 non possono superare /64.
x.lower() Restituisce il valore minuscolo della stringa x.
x.upper() Restituisce il valore in maiuscolo della stringa x.
x.base64Decode() Restituisce il valore decodificato in base64 di x. I caratteri _ - vengono prima sostituiti rispettivamente con / +. Restituisce "" (stringa vuota) se x non è un valore base64 valido.
has(m['k']) Restituisce true se la chiave k è disponibile nella mappa m.
m['k'] Restituisce il valore alla chiave k nella mappa stringa-stringa m se k è disponibile. In caso contrario, restituisce un errore. L'approccio consigliato consiste nel verificare innanzitutto la disponibilità utilizzando "has(m['k'])==true".
int(x) Converte il risultato della stringa di x in un tipo int. Può quindi essere utilizzata per fare un confronto di numeri interi mediante operatori aritmetici standard come > e <=. Funziona solo per i valori che dovrebbero essere numeri interi.
size(x) Restituisce la lunghezza della stringa x.
x.urlDecode() Restituisce il valore decodificato dall'URL di x. Le sequenze di caratteri in formato %## vengono sostituite con gli equivalenti non ASCII e + viene sostituito con uno spazio. Vengono restituite codifiche non valide così come sono.
x.urlDecodeUni() Restituisce il valore x decodificato nell'URL. Oltre a urlDecode(), gestisce anche le sequenze di caratteri Unicode in formato %u###. Vengono restituite codifiche non valide così come sono.
x.utf8ToUnicode() Restituisce la rappresentazione Unicode minuscolo di una x con codifica UTF-8.

Espressioni di esempio

Per ognuna di queste espressioni, l'azione intrapresa dipende dall'inclusione dell'espressione in una regola di negazione o di autorizzazione.

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

  • La seguente espressione corrisponde a richieste dell'intervallo di indirizzi IP 198.51.100.0/24:

    inIpRange(origin.ip, '198.51.100.0/24')
    
  • La seguente espressione corrisponde a richieste dell'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 creare una 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 contengono 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 che hanno un'intestazione referer non vuota:

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

Consenti o nega il traffico in base all'URL dell'host nell'intestazione

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

    request.headers['host'].lower().contains('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 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 l'espressione seguente, che corrisponde alle richieste da tutte le aree geografiche diverse dalla regione AU:

    origin.region_code != 'AU'
    

I codici regione sono basati sui codici ISO 3166-1 alpha 2 In alcuni casi, una regione corrisponde a un paese, ma non sempre. 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 bloccarlo.

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

    origin.asn == 123
    

In alternativa, se la tua applicazione web deve essere disponibile solo ai clienti che utilizzano uno specifico operatore di rete, 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 vuoi autorizzare:

    origin.asn != 123
    

Espressioni multiple

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

  • Nel seguente esempio, le richieste da parte di 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 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 di richiesta che corrisponde a un'espressione regolare

  • La seguente espressione corrisponde a richieste che contengono la stringa bad_path nell'URI:

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

    request.headers['user-agent'].matches('Chrome')
    
  • La seguente espressione mostra una 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 contenente un valore decodificato in base64 specifico

  • La seguente espressione corrisponde alle richieste che hanno 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 contenente 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 una lunghezza dell'intestazione x-data maggiore o uguale a 1024 caratteri:

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

Consenti o nega il traffico che non contiene content-length nel corpo HTTP

  • La seguente espressione corrisponde alle richieste che hanno un valore content-length pari a zero nel corpo HTTP:

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

Consenti o nega il traffico contenente un valore specifico dell'URL codificato

  • 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 contenente un valore specifico dell'URL codificato di una stringa Unicode

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

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

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

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

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

Consenti o nega il traffico in base a un'impronta JA3 nota

  • La seguente espressione corrisponde alle richieste che hanno un'impronta JA3 uguale a e7d705a3286e19ea42f587b344ee6865:

    origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865'
    

Consenti o nega il traffico in base a un elenco di impronte JA3

  • La seguente espressione corrisponde alle richieste che hanno un'impronta JA3 uguale a una delle seguenti fingerprint JA3:

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

Regole WAF preconfigurate

Le regole WAF preconfigurate utilizzano firme statiche preconfigurate, espressioni regolari o entrambe per creare corrispondenze nel corpo HTTP POST, nelle intestazioni delle richieste HTTP e parametri di ricerca. Le regole WAF preconfigurate disponibili si basano sul set di regole di base di Modsecurity OWASP versione 3.3. Google Cloud Armor fornisce diverse regole WAF preconfigurate predefinite. Per un elenco completo delle regole WAF preconfigurate, consulta la panoramica delle regole WAF preconfigurate di Google Cloud Armor.

Per elencare tutte le regole WAF preconfigurate disponibili, consulta Elenco di regole WAF preconfigurate disponibili.

Per ulteriori informazioni sulle regole WAF preconfigurate, consulta il caso d'uso Mitigare 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>-<ModSecurity CRS version>-<version field>. La categoria di attacco specifica il tipo di attacchi da cui vuoi proteggerti, ad esempio xss (cross-site scripting) o sqli (SQL injection).

I campi delle versioni 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 passate alla versione stable.

ID membri delle regole WAF preconfigurate

Una regola WAF preconfigurata contiene diverse espressioni, ciascuna con la propria firma. Ad esempio, la regola WAF preconfigurata xss-v33-stable include un'espressione denominata owasp-crs-v030301-id941100-xss, che corrisponde all'ID regola id941100 per la versione 3.3. Puoi utilizzare le firme per escludere determinate espressioni dall'utilizzo, il che è utile se una determinata espressione attiva costantemente un falso positivo. Per ulteriori informazioni, consulta le informazioni per la risoluzione dei problemi relativi ai falsi positivi.

Per informazioni sulla serie di regole principali e sull'ottimizzazione a diversi livelli di sensibilità, consulta Ottimizzazione delle regole WAF di Google Cloud Armor.

Operatore per regole WAF preconfigurate

Espressioni Descrizione
evaluatePreconfiguredWaf(string, MAP<string, dyn>) Restituisce true se una qualsiasi delle firme WAF all'interno del set di regole WAF specificato restituisce true. Il primo argomento è il nome della serie di regole WAF, ad esempio xss-v33-stable. Il secondo argomento (facoltativo) è una mappa in cui la chiave è una stringa e il valore viene digitato dinamicamente in base alla chiave. Lo scopo di questa argomentazione è perfezionare le firme WAF che vengono valutate. Le chiavi accettate includono:
  • "sensitivity": corrisponde al livello di paranoia ModSecurity Core Rule Set, che ha 4 livelli, che vanno 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_id" (descritto più avanti). Quando specifichi una sensibilità di 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": le firme WAF (rappresentate da ID regola) di cui disattivare la valutazione, in cui il set di base è determinato dal valore di sensibilità. Il suo valore è un elenco di stringhe. Il numero massimo consentito di ID regola è 128.
  • "opt_in_rule_ids": firme WAF (rappresentate da 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 consentito è 128. Quando lo utilizzi, è necessario specificare una "sensibilità" pari a 0.

Le chiavi "opt_out_rule_id" 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 verranno aggiunte in un secondo momento a un set di regole esistente.

evaluatePreconfiguredExpr(string, LIST)

Restituisce true se una qualsiasi 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 di ID separati da virgole che devono essere esclusi 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-v33-stable per attenuare gli attacchi XSS:

    evaluatePreconfiguredExpr('xss-v33-stable')
    
  • La seguente espressione utilizza tutte le espressioni della regola WAF preconfigurata xss-v33-stable, ad eccezione degli ID membro 941100 e 941110:

    evaluatePreconfiguredExpr('xss-v33-stable', ['owasp-crs-v030301-id941100-xss',
    'owasp-crs-v030301-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') && evaluatePreconfiguredExpr('sqli-v33-stable')
    

Passaggi successivi