Chaque règle de stratégie de sécurité Google Cloud Armor possède une priorité, une condition de correspondance et une action. Google Cloud Armor exécute l'action de la règle de priorité la plus élevée qui correspond à une requête. Les règles dont la priorité est inférieure à celle de la règle de correspondance de priorité la plus élevée ne sont pas évaluées, même si elles ont les mêmes conditions de correspondance.
Chaque règle de stratégie de sécurité accepte deux types de conditions de correspondance:
- Une condition de correspondance de base contient des listes d'adresses IP ou des listes de plages d'adresses IP. Les conditions de correspondance de base sont définies à l'aide de l'option
--src-ip-ranges
lorsque vous créez une règle à l'aide de Google Cloud CLI. - Une condition de correspondance avancée contient une expression avec jusqu'à cinq sous-expressions pouvant correspondre à divers attributs d'une requête entrante.
Les conditions de correspondance avancées sont définies à l'aide de l'indicateur
--expression
lorsque vous créez une règle à l'aide de Google Cloud CLI.
Cette page présente les conditions de correspondance avancées et le langage des règles personnalisées Google Cloud Armor que vous utilisez pour écrire des expressions dans les conditions de correspondance avancées des règles de stratégie de sécurité. Le langage des règles personnalisées Google Cloud Armor est un sous-ensemble de Common Expression Language (CEL). Les expressions écrites dans le langage de règles personnalisées de Google Cloud Armor nécessitent deux composants:
- Attribut: données à inspecter
- L'opération: comment utiliser les données
Par exemple, l'expression suivante utilise les attributs origin.ip
et 9.9.9.0/24
dans l'opération inIpRange()
. Dans ce cas, l'expression renvoie "true" si origin.ip
est compris dans la plage d'adresses IP 9.9.9.0/24
.
inIpRange(origin.ip, '9.9.9.0/24')
Même si l'exemple d'expression précédent ne correspond qu'à l'adresse IP source, lorsque vous utilisez l'exemple d'expression dans une règle de stratégie de sécurité Google Cloud Armor, la règle est considérée comme une règle avec des conditions de correspondance avancées du point de vue des quotas. Pour en savoir plus, consultez la page Quotas et limites de Google Cloud Armor.
Attributs
Les attributs représentent des informations provenant d'une requête entrante, telles que l'adresse IP d'origine ou le chemin d'URL demandé.
Champ | Type | Description du champ |
---|---|---|
origin.ip |
chaîne | Adresse IP source de la requête. |
origin.user_ip |
chaîne | Adresse IP du client d'origine, incluse dans HTTP-HEADER par un proxy en amont. Avant d'utiliser cet attribut, vous devez configurer l'option userIpRequestHeaders[] dans le champ advancedOptionsConfig de la stratégie de sécurité pour qu'elle corresponde à une source telle que True-Client-IP , X-Forwarded-For ou X-Real-IP .
Si vous ne configurez pas l'option |
origin.tls_ja3_fingerprint |
chaîne | Empreinte TLS/SSL JA3 si le client se connecte via HTTPS , HTTP/2 ou HTTP/3 . Si ce n'est pas le cas, une chaîne vide est renvoyée. |
request.headers |
carte | Mappage chaîne à chaîne des en-têtes de requête HTTP. Si un en-tête contient plusieurs valeurs, la valeur figurant dans ce mappage est une chaîne de toutes les valeurs de l'en-tête, séparées par des virgules. Les clés de ce mappage sont toutes en minuscules. Tous les en-têtes acceptés par les équilibreurs de charge d'application externes sont inspectés, et les mêmes limites s'appliquent. L'approche recommandée consiste à vérifier d'abord la disponibilité à l'aide de |
request.method |
chaîne | Méthode de requête HTTP, telle que GET ou POST . |
request.path |
chaîne | Chemin d'URL HTTP demandé. |
request.scheme |
chaîne | Schéma d'URL HTTP, tel que http ou https .
Les valeurs de cet attribut sont toutes en minuscules. |
request.query |
chaîne | Requête d'URL HTTP au format name1=value&name2=value2 , telle qu'elle apparaît sur la première ligne de la requête HTTP. Aucun décodage n'est effectué
|
origin.region_code |
chaîne | Code pays Unicode associé à l'adresse IP d'origine, tel que US . Si vous créez une règle ou une expression qui utilise des codes de pays ou de région ISO 3166-1 alpha-2, Google Cloud Armor traite chaque code indépendamment. Les règles et expressions Google Cloud Armor utilisent explicitement ces codes de région pour autoriser ou refuser des requêtes.
Pour plus d'informations, consultez la section unicode_region_subtag de la spécification Unicode Technical Standard. |
origin.asn |
Entier | Numéro ASN (Autonomous System Number) associé à l'adresse IP d'origine Le numéro ASN unique est déterminé en fonction de l'opérateur réseau qui accepte les préfixes d'adresse IP contenant l'adresse IP d'origine. |
Attributs reCAPTCHA
Cette section liste les attributs qui ne s'appliquent qu'aux jetons ou aux cookies d'exception reCAPTCHA. Une sous-expression basée sur ces attributs renvoie false
si le jeton ou le cookie d'exception reCAPTCHA à évaluer n'est pas disponible ou n'est pas valide pour l'une des raisons suivantes:
- Le jeton est incorrect et ne peut pas être décodé.
- Le jeton contient des attributs non valides. Par exemple, le jeton a été généré à l'aide d'une clé reCAPTCHA qui ne correspond pas aux clés reCAPTCHA associées à la règle.
- Le jeton a expiré.
Attributs des cookies d'exception
Champ | Type | Description du champ |
---|---|---|
token.recaptcha_exemption.valid |
bool |
Présence d'un cookie d'exception reCAPTCHA valide. |
Attributs des jetons d'action
Champ | Type | Description du champ |
---|---|---|
token.recaptcha_action.score |
float |
Score d'un jeton d'action reCAPTCHA. Un score valide varie de 0.0 à 1.0 , où 0.0 désigne très probablement un utilisateur illégitime et 1.0 désigne très probablement un utilisateur légitime. |
token.recaptcha_action.captcha_status |
string |
État captcha d'un jeton reCAPTCHA. Un état valide est NONE , PASS ou FAIL , où NONE fait référence à l'absence de questions d'authentification lors de l'évaluation reCAPTCHA, de sorte que le champ captcha ne figure pas dans le jeton d'action. |
token.recaptcha_action.action |
string |
Nom de l'action (jusqu'à 100 caractères) provenant d'un jeton d'action reCAPTCHA Enterprise. Consultez la section Noms des actions. |
token.recaptcha_action.valid |
bool |
Présence d'un jeton d'action reCAPTCHA valide. |
Attributs des jetons de session
Champ | Type | Description du champ |
---|---|---|
token.recaptcha_session.score |
float |
Score d'un jeton de session reCAPTCHA. Un score valide varie de 0.0 à 1.0 , où 0.0 désigne très probablement un utilisateur illégitime et 1.0 désigne très probablement un utilisateur légitime. |
token.recaptcha_session.valid |
bool |
Présence d'un jeton de session reCAPTCHA valide. |
Opérations
La documentation de référence suivante décrit les opérateurs que vous pouvez utiliser avec des attributs (représentés par x
, y
et k
) pour définir des expressions de règle.
Description | Description |
---|---|
x == "foo" |
Renvoie "true" si x est égal au littéral de chaîne constante donné. |
x == R"fo'o" |
Renvoie "true" si x est égal au littéral de chaîne brute donné qui n'interprète pas les séquences d'échappement. Les littéraux de chaîne brute sont pratiques pour exprimer des chaînes qui doivent elles-mêmes utiliser des caractères de séquence d'échappement. |
x == y |
Renvoie "true" si x est égal à y. |
x != y |
Renvoie "true" si x n'est pas égal à y. |
x + y |
Renvoie la chaîne concaténée xy. |
x && y |
Renvoie "true" si x et y sont vrais. |
x || y |
Renvoie "true" si x, y ou les deux sont vrais. |
!x |
Renvoie "true" si la valeur booléenne x est fausse ou renvoie "false" si la valeur booléenne x est vraie. |
x.contains(y) |
Renvoie "true" si la chaîne x contient la sous-chaîne y. |
x.startsWith(y) |
Renvoie "true" si la chaîne x commence par la sous-chaîne y. |
x.endsWith(y) |
Renvoie "true" si la chaîne x se termine par la sous-chaîne y. |
x.matches(y) |
Renvoie "true" si la chaîne x est partiellement mise en correspondance par le modèle RE2 y spécifié. Le modèle RE2 est compilé à l'aide de l'option RE2::Latin1 qui désactive les fonctionnalités Unicode. |
inIpRange(x, y) |
Renvoie la valeur "true" si l'adresse IP x est comprise dans la plage d'adresses IP y. |
x.lower() |
Renvoie la valeur en minuscules de la chaîne x. |
x.upper() |
Renvoie la valeur en majuscules de la chaîne x. |
x.base64Decode() |
Renvoie la valeur décodée en base64 de x. Les caractères _ - sont d'abord remplacés par / + respectivement.
Renvoie "" (chaîne vide) si x n'est pas une valeur base64 valide. |
has(m['k']) |
Renvoie "true" si la clé k est disponible dans le mappage m. |
m['k'] |
Renvoie la valeur à la clé k dans le mappage chaîne à chaîne m si k est disponible. Sinon, renvoie une erreur. L'approche recommandée consiste à vérifier d'abord la disponibilité à l'aide de "has(m['k'])==true" . |
int(x) |
Convertit le résultat de chaîne de x en type int . Il peut ensuite être utilisé pour établir une comparaison d'entiers à l'aide d'opérateurs arithmétiques standards tels que ">" et "<=". Cela ne fonctionne que pour les valeurs qui sont supposées être des entiers. |
size(x) |
Renvoie la longueur de la chaîne x. |
x.urlDecode() |
Renvoie la valeur décodée par l'URL de x. Les séquences de caractères au format %## sont remplacées par des équivalents non-ASCII, et + par une espace. Les encodages non valides sont renvoyés tels quels. |
x.urlDecodeUni() |
Renvoie la valeur décodée par l'URL de x. En plus de urlDecode() , cette fonction gère également les séquences de caractères Unicode au format %u### . Les encodages non valides sont renvoyés tels quels. |
x.utf8ToUnicode() |
Renvoie la représentation Unicode en minuscules d'un x encodé en UTF-8. |
Exemples d'expressions
Pour chacune de ces expressions, l'action entreprise varie selon que l'expression est incluse dans une règle de refus ou d'autorisation.
Autoriser ou refuser l'accès en fonction d'une plage d'adresses IP en IPv4 ou IPv6
L'expression suivante correspond aux requêtes provenant de la plage d'adresses IP
198.51.100.0/24
:inIpRange(origin.ip, '198.51.100.0/24')
L'expression suivante correspond aux requêtes provenant de la plage d'adresses IP
2001:db8::/32
:inIpRange(origin.ip, '2001:db8::/32')
Autoriser ou refuser l'accès en fonction d'une plage d'adresses IP client personnalisée derrière un proxy en amont
Si vous avez configuré l'opérateur origin.user_ip
, vous pouvez effectuer une correspondance en fonction des valeurs d'en-tête que vous avez spécifiées dans votre champ advancedOptionsConfig.userIpRequestHeaders[]
.
L'expression suivante correspond aux requêtes provenant de la plage d'adresses IP
192.0.2.0/24
:inIpRange(origin.user_ip, '192.0.2.0/24')
L'expression suivante correspond aux requêtes provenant de la plage d'adresses IP
2001:db8::/32
:inIpRange(origin.user_ip, '2001:db8::/32')
Autoriser ou refuser le trafic avec un cookie spécifique
L'expression suivante correspond aux requêtes qui présentent un cookie contenant
80=BLAH
:has(request.headers['cookie']) && request.headers['cookie'].contains('80=BLAH')
Autoriser ou refuser le trafic avec un en-tête referer
non vide
L'expression suivante correspond aux requêtes qui ont un en-tête
referer
non vide :has(request.headers['referer']) && request.headers['referer'] != ""
Autoriser ou refuser le trafic en fonction de l'URL de l'hôte dans l'en-tête
L'expression suivante correspond aux requêtes adressées à une URL spécifique :
request.headers['host'].lower().contains('test.example.com')
Autoriser ou refuser le trafic provenant d'une région spécifique
Si votre application Web n'est pas disponible dans la région AU
, toutes les requêtes provenant de cette région doivent être bloquées.
Dans une règle de refus, utilisez l'expression suivante, qui correspond aux requêtes de la région
AU
:origin.region_code == 'AU'
Si votre application Web est exclusivement disponible dans la région AU
, les requêtes provenant de toutes les autres régions doivent être bloquées.
Dans une règle de refus, utilisez l'expression suivante pour faire correspondre les requêtes de toutes les régions autres que la région
AU
:origin.region_code != 'AU'
Les codes de région sont basés sur les codes ISO 3166-1 alpha-2. Dans certains cas, une région correspond à un pays, mais ce n'est pas toujours le cas. Par exemple, le code US
comprend tous les États des États-Unis, un district et six zones périphériques.
Autoriser ou refuser le trafic provenant d'un numéro ASN spécifique
Si votre application Web doit être bloquée pour les clients desservis par un opérateur réseau spécifique, vous pouvez utiliser le numéro ASN de l'opérateur réseau à bloquer.
Dans une règle de refus, utilisez l'expression suivante, qui identifie les requêtes provenant d'un numéro ASN spécifique :
origin.asn == 123
Si votre application Web doit être exclusivement disponible pour les clients situés derrière un opérateur réseau spécifique, les requêtes de tous les autres opérateurs réseau doivent être bloquées.
Dans une règle de refus, utilisez l'expression suivante, qui identifie tous les autres opérateurs réseau autres que celui que vous souhaitez autoriser:
origin.asn != 123
Expressions multiples
Pour inclure plusieurs conditions dans une seule règle, combinez plusieurs sous-expressions.
Dans l'exemple suivant, les requêtes provenant de
1.2.3.0/24
(comme vos testeurs alpha) dans la régionAU
correspondent à l'expression suivante :origin.region_code == "AU" && inIpRange(origin.ip, '1.2.3.0/24')
L'expression suivante correspond aux requêtes provenant de
1.2.3.4
où un en-tête user-agent contient la chaîneWordPress
:inIpRange(origin.ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('WordPress')
Autoriser ou refuser le trafic pour un URI de requête qui correspond à une expression régulière
L'expression suivante correspond aux requêtes dont l'URI contient la chaîne
example_path
:request.path.matches('/example_path/')
L'expression suivante correspond aux requêtes dont le champ d'en-tête
User-Agent
contientChrome
:request.headers['user-agent'].matches('Chrome')
L'expression suivante montre une correspondance non sensible à la casse pour l'en-tête
User-Agent
contenantwordpress
. Elle correspond àUser-Agent:WordPress/605.1.15
,User-Agent:wordPress
et d'autres variantes dewordpress
:request.headers['user-agent'].matches('(?i:wordpress)')
Autoriser ou refuser le trafic contenant une valeur décodée en base64 spécifique
L'expression suivante correspond aux requêtes qui ont la valeur décodée en base64
myValue
pour l'en-têteuser-id
:has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')
Autoriser ou refuser le trafic contenant une valeur de chaîne d'une longueur spécifique
L'expression suivante correspond aux requêtes dont l'URL est plus longue que 10 caractères:
size(request.path) > 10
L'expression suivante correspond aux requêtes dont la longueur de l'en-tête
x-data
est supérieure ou égale à 1 024 caractères:size(request.headers['x-data']) >= 1024
Autoriser ou refuser le trafic dont le corps HTTP contient un en-tête content-length
nul
L'expression suivante correspond aux requêtes dont le corps HTTP contient un en-tête
content-length
nul :int(request.headers["content-length"]) == 0
Autoriser ou refuser le trafic contenant une valeur encodée sous forme d'une URL spécifique
L'expression suivante correspond aux requêtes qui présentent une valeur de cookie contenant
%3c
:has(request.headers['cookie']) && request.headers['cookie'].urlDecode().contains('<')
Autoriser ou refuser le trafic contenant une valeur de chaîne Unicode encodée sous forme d'une URL spécifique
L'expression suivante correspond aux requêtes dont la valeur de cookie est égale à
Match%2BValue
ouMatch%u002BValue
:has(request.headers['cookie']) && request.headers['cookie'].urlDecodeUni() == 'Match+Value'
Autoriser ou refuser le trafic contenant une chaîne Unicode spécifique d'un texte UTF-8
L'expression suivante correspond aux requêtes dont la valeur de cookie est égale à
¬
:has(request.headers['cookie']) && request.headers['cookie'].utf8ToUnicode() == '%u00ac'
Autoriser ou refuser le trafic en fonction d'une empreinte JA3 connue
L'expression suivante correspond aux requêtes dont l'empreinte JA3 est égale à
e7d705a3286e19ea42f587b344ee6865
:origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865'
Autoriser ou refuser le trafic en fonction d'une liste d'empreintes JA3
L'expression suivante correspond aux requêtes dont l'empreinte JA3 est égale à l'une des empreintes JA3 suivantes:
e7d705a3286e19ea42f587b344ee6865
f8a5929f8949e846267b582072e35f84
8f8b62163873a62234c14f15e7b88340
origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865' || origin.tls_ja3_fingerprint == 'f8a5929f8949e846267b582072e35f84' || origin.tls_ja3_fingerprint == '8f8b62163873a62234c14f15e7b88340'
Règles WAF préconfigurées
Les règles WAF préconfigurées utilisent des signatures statiques préconfigurées, des expressions régulières ou les deux pour mettre en correspondance le corps POST HTTP, les en-têtes de requête HTTP et les paramètres de requête. Les règles WAF préconfigurées disponibles sont basées sur l'ensemble de règles de base OWASP ModSecurity version 3.3. Google Cloud Armor fournit plusieurs règles WAF préconfigurées. Pour obtenir la liste complète des règles WAF préconfigurées, consultez la présentation des règles WAF préconfigurées de Google Cloud Armor.
Pour répertorier toutes les règles WAF préconfigurées disponibles, consultez la section Répertorier les règles WAF préconfigurées disponibles.
Pour plus d'informations sur les règles WAF préconfigurées, consultez le cas d'utilisation Atténuer les attaques de couche d'application à l'aide de règles WAF préconfigurées.
Noms des règles WAF préconfigurées
Les noms des règles WAF préconfigurées suivent le format <attack category>-<ModSecurity CRS version>-<version field>
. La catégorie d'attaque spécifie le type d'attaques contre lesquelles vous souhaitez vous protéger, comme xss
(script intersites) ou sqli
(injection SQL).
Les champs de version compatibles sont stable
et canary
. Les ajouts et changements effectués dans les règles sont d'abord publiés dans la version canary
. Lorsque des ajouts et des changements sont considérés comme sûrs et stables, ils sont promus vers la version stable
.
ID des membres de la règle WAF préconfigurée
Une règle WAF préconfigurée contient plusieurs expressions, chacune avec sa signature.
Par exemple, la règle WAF préconfigurée xss-v33-stable
inclut une expression appelée owasp-crs-v030301-id941100-xss
, qui correspond à l'ID de règle id941100
pour la version 3.3. Vous pouvez utiliser les signatures pour empêcher l'utilisation d'expressions spécifiques, ce qui est utile si une expression particulière déclenche systématiquement un faux positif. Pour plus d'informations, consultez les informations de dépannage concernant les faux positifs.
Pour plus d'informations sur l'ensemble de règles de base et l'ajustement à différents niveaux de sensibilité, consultez la page Ajuster les règles WAF Google Cloud Armor.
Opérateur pour les règles WAF préconfigurées
Expressions | Description |
---|---|
evaluatePreconfiguredWaf(string, MAP<string, dyn>) |
Renvoie "true" si l'une des signatures WAF figurant dans l'ensemble de règles WAF spécifié renvoie "true". Le premier argument est le nom de l'ensemble de règles du WAF, par exemple xss-v33-stable . Le deuxième argument (facultatif) est un mappage dans lequel la clé est une chaîne et la valeur est typée dynamiquement en fonction de la clé. L'objectif de cet argument est d'affiner les signatures WAF évaluées. Les clés acceptées sont les suivantes :
Les clés "opt_out_rule_ids" et "opt_in_rule_ids" s'excluent mutuellement. Vous pouvez choisir d'utiliser "opt_in_rule_ids" si vous souhaitez examiner et activer manuellement les nouvelles signatures WAF qui sont ajoutées ultérieurement à un ensemble de règles existant. |
evaluatePreconfiguredExpr(string, LIST) |
Renvoie "true" si l'une des expressions figurant dans la règle WAF préconfigurée spécifiée renvoie "true". Le premier argument est le nom de la règle WAF préconfigurée, par exemple |
Exemples de règles WAF préconfigurées
L'expression suivante utilise la règle WAF préconfigurée
xss-v33-stable
pour atténuer les attaques XSS :evaluatePreconfiguredExpr('xss-v33-stable')
L'expression suivante utilise toutes les expressions de la règle WAF préconfigurée
xss-v33-stable
, à l'exception des ID membres941100
et941110
:evaluatePreconfiguredExpr('xss-v33-stable', ['owasp-crs-v030301-id941100-xss', 'owasp-crs-v030301-id941110-xss'])
L'expression suivante utilise une règle WAF préconfigurée pour atténuer les attaques SQLi à partir de la plage d'adresses IP
198.51.100.0/24
:inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredExpr('sqli-v33-stable')
Étapes suivantes
- Configurez des stratégies, des règles et des expressions de sécurité.
- Ajustez les règles de pare-feu d'application Web (WAF).
- Résoudre les problèmes