Comment puis-je exclure des URI spécifiques de l'inspection XSS ou SQLi pour les requêtes HTTP dans AWS WAF ?

Lecture de 6 minute(s)
0

Lorsque j'utilise le pare-feu d'applications Web (AWS WAF), j'obtiens des faux positifs pour l'injection SQL (SQLi) ou les scripts inter-site (XSS) pour certaines requêtes HTTP. Je souhaite exclure des URI spécifiques de l'inspection XSS ou SQLi pour les requêtes HTTP.

Brève description

L'inspection XSS et SQLi des règles gérées par AWS et des règles personnalisées peut parfois produire de faux positifs. Pour éviter ce problème, vous pouvez exclure des chemins d'URI spécifiques de l'inspection XSS et SQLi. Pour ce faire, utilisez des instructions imbriquées pour rédiger une règle de blocage avec des exceptions, afin qu'AWS WAF évalue la requête par rapport à toutes les autres règles.

Résolution

Exemple de requête HTTP ou HTTPS

http://www.amazon.com/path/string1?xss=%3Cscript%3E%3Cscript%3E&sql=UNION%20ALL%20SELECT%201

Dans cette requête, le chemin de l'URI est /path/string1. La chaîne qui suit le point d'interrogation (?) est la chaîne de requête. Dans cet exemple, la chaîne de requête est xss=%3Cscript%3E%3Cscript%3E&sql=UNION%20ALL%20SELECT%201.

Exemples de règles permettant d'autoriser des URI spécifiques à partir de l'inspection XSS ou SQLi

Remarque : les exemples de configuration de règles suivants sont fournis à titre de référence uniquement. Vous devez personnaliser ces règles au niveau de PositionalConstraint, SearchString, TextTransformations, etc. Vous pouvez utiliser une logique similaire pour autoriser des en-têtes, des paramètres de requête spécifiques, etc.

Cas n°1 : utilisation de règles gérées par AWS

Le groupe de règles gérées par AWS AWSManagedRulesCommonRuleSet contient les règles suivantes :

  • CrossSiteScripting_COOKIE
  • CrossSiteScripting_QUERYARGUMENTS
  • CrossSiteScripting_BODY
  • CrossSiteScripting_URIPATH

Le groupe de règles AWSManagedRulesCommonRuleSet possède une action de blocage (BLOCK) qui inspecte la présence d'une chaîne d'attaque XSS dans la partie correspondante de la demande. Pour en savoir plus, reportez-vous à Groupe de règles géré par un ensemble de règles de base (CRS).

De même, le groupe de règles AWSManagedRulesSQLiRuleSet possède des règles pour inspecter les paramètres de requête, le corps, le chemin de l'URI et un cookie pour détecter un modèle d'attaque par injection SQLi. Pour en savoir plus,reportez-vous à Groupes de règles spécifiques aux cas d'utilisation.

Lorsqu'une demande répond à ces règles, AWS WAF génère les étiquettes correspondantes. Votre règle personnalisée dans l'ACL WEB peut ensuite utiliser ces étiquettes de règles gérées par AWS pour exclure de manière sélective certaines demandes spécifiques des signatures de règles correspondantes.

Pour autoriser des URI spécifiques, procédez comme suit :

1. Conservez les règles suivantes du groupe de règles AWSManagedRulesCommonRuleSet en mode Nombre :

  • CrossSiteScripting_COOKIE
  • CrossSiteScripting_QUERYARGUMENTS
  • CrossSiteScripting_BODY
  • CrossSiteScripting_URIPATH

2. Créez une règle comportant une action de blocage avec des exceptions pour les chemins d'URI. Configurez la règle avec une priorité inférieure à celle d'AWSManagedRulesCommonRuleSet. Pour configurer une priorité inférieure dans la console AWS WAF, il vous suffit de placer la règle plus bas dans la liste. Pour configurer une priorité inférieure dans JSON, vous devez utiliser une valeur de Priorité plus élevée.

La règle suit la logique suivante :

(XSS_URIPATH ou XSS_Cookie ou XSS_Body ou XSS_QueryArguments) ET (URIString non autorisé sur la liste) = BLOCK

Utilisez la configuration suivante :

{
  "Name": "whitelist-xss",
  "Priority": 10,
  "Statement": {
    "AndStatement": {
      "Statements": \[
        {
          "OrStatement": {
            "Statements": \[
              {
                "LabelMatchStatement": {
                  "Scope": "LABEL",
                  "Key": "awswaf:managed:aws:core-rule-set:CrossSiteScripting\_URIPath"
                }
              },
              {
                "LabelMatchStatement": {
                  "Scope": "LABEL",
                  "Key": "awswaf:managed:aws:core-rule-set:CrossSiteScripting\_Cookie"
                }
              },
              {
                "LabelMatchStatement": {
                  "Scope": "LABEL",
                  "Key": "awswaf:managed:aws:core-rule-set:CrossSiteScripting\_Body"
                }
              },
              {
                "LabelMatchStatement": {
                  "Scope": "LABEL",
                  "Key": "awswaf:managed:aws:core-rule-set:CrossSiteScripting\_QueryArguments"
                }
              }
            \]
          }
        },
        {
          "NotStatement": {
            "Statement": {
              "ByteMatchStatement": {
                "SearchString": "/path/string1",
                "FieldToMatch": {
                  "UriPath": {}
                },
                "TextTransformations": \[
                  {
                    "Priority": 0,
                    "Type": "NONE"
                  }
                \],
                "PositionalConstraint": "CONTAINS"
              }
            }
          }
        }
      \]
    }
  },
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "whitelist-xss"
  }
}

Remarque : dans cet exemple, l'instruction OrStatement exclut des URI spécifiques de toutes les étiquettes et de toutes les parties de la requête Web : corps, en-têtes, chemin d'URI et arguments de requête. Cet exemple suppose que vous avez rencontré un faux positif pour le même URI dans toutes les parties de la requête Web. Il est toutefois possible de rencontrer un faux positif dans une seule partie de la requête Web, par exemple dans les arguments de la requête. Dans ce cas, il est recommandé de créer une règle distincte pour cette partie de la requête Web et son étiquette correspondante uniquement. Dans le cadre de cette règle distincte, le chemin d'URL spécifique ne doit pas être exclu de toutes les parties de la requête Web.

Suivez les mêmes étapes pour AWSManagedRulesSQLiRuleSet, mais remplacez les étiquettes par celles générées par AWSManagedRulesSQLiRuleSet.

Si vous souhaitez exclure plusieurs URI de l'inspection, utilisez OrStatement dans NotStatement. Par exemple, pour exclure /path/string1 et /path/string2, utilisez le NotStatement suivant :

{
  "NotStatement": {
    "Statement": {
      "OrStatement": {
        "Statements": \[
          {
            "ByteMatchStatement": {
              "SearchString": "/path/string1",
              "FieldToMatch": {
                "UriPath": {}
              },
              "TextTransformations": \[
                {
                  "Priority": 0,
                  "Type": "NONE"
                }
              \],
              "PositionalConstraint": "CONTAINS"
            }
          },
          {
            "ByteMatchStatement": {
              "SearchString": "/path/string2",
              "FieldToMatch": {
                "UriPath": {}
              },
              "TextTransformations": \[
                {
                  "Priority": 0,
                  "Type": "NONE"
                }
              \],
              "PositionalConstraint": "CONTAINS"
            }
          }
        \]
      }
    }
  }
}

Cas n°2 : utilisation de règles XSS et SQLi personnalisées

La règle suit la logique suivante :

(XSS_URIPATH ou XSS_Cookie ou XSS_Body ou XSS_QueryArguments) ET (URIString non autorisé sur la liste) = BLOCK

Utilisez la configuration de règles suivante pour inspecter les chaînes d'attaque XSS associées à la demande, mais également pour exclure de manière sélective un URI_PATH spécifique :

{
  "Name": "xss-URI",
  "Priority": 10,
  "Action": {
    "Block": {}
  },
  "VisibilityConfig": {
    "SampledRequestsEnabled": true,
    "CloudWatchMetricsEnabled": true,
    "MetricName": "xss-URI"
  },
  "Statement": {
    "AndStatement": {
      "Statements": \[
        {
          "OrStatement": {
            "Statements": \[
              {
                "XssMatchStatement": {
                  "FieldToMatch": {
                    "UriPath": {}
                  },
                  "TextTransformations": \[
                    {
                      "Priority": 0,
                      "Type": "NONE"
                    }
                  \]
                }
              },
              {
                "XssMatchStatement": {
                  "FieldToMatch": {
                    "Cookies": {
                      "MatchPattern": {
                        "All": {}
                      },
                      "MatchScope": "ALL",
                      "OversizeHandling": "CONTINUE"
                    }
                  },
                  "TextTransformations": \[
                    {
                      "Priority": 0,
                      "Type": "NONE"
                    }
                  \]
                }
              },
              {
                "XssMatchStatement": {
                  "FieldToMatch": {
                    "Body": {
                      "OversizeHandling": "CONTINUE"
                    }
                  },
                  "TextTransformations": \[
                    {
                      "Priority": 0,
                      "Type": "NONE"
                    }
                  \]
                }
              },
              {
                "XssMatchStatement": {
                  "FieldToMatch": {
                    "AllQueryArguments": {}
                  },
                  "TextTransformations": \[
                    {
                      "Priority": 0,
                      "Type": "NONE"
                    }
                  \]
                }
              }
            \]
          }
        },
        {
          "NotStatement": {
            "Statement": {
              "ByteMatchStatement": {
                "FieldToMatch": {
                  "UriPath": {}
                },
                "PositionalConstraint": "CONTAINS",
                "SearchString": "/path/string1",
                "TextTransformations": \[
                  {
                    "Type": "NONE",
                    "Priority": 0
                  }
                \]
              }
            }
          }
        }
      \]
    }
  }
}

Veuillez suivre cette procédure lorsque vous utilisez des instructions SQLi.

Remarque : il n'est pas recommandé de créer une règle avec une priorité plus élevée pour autoriser un seul URI. La demande contenant l'URI_PATH autorisé ne pourrait alors plus être évaluée par rapport à toutes les autres règles définies dans l'ACL Web.

Informations connexes

Principes de base des énoncés de règles

Énoncé de règle d'attaque par scripts inter-site

Énoncé de règle d'attaque par injection SQL

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 9 mois