Atualizar a versão do conjunto de regras CRS ou DRS

Aplica-se a: ✔️ Application Gateway V2

O Conjunto de Regras Padrão (DRS) gerenciado pelo Azure no WAF (Firewall de Aplicativo Web) do Gateway de Aplicativo do Azure protege aplicativos Web contra vulnerabilidades e explorações comuns, incluindo os 10 principais tipos de ataque do OWASP. O conjunto de regras padrão também incorpora as regras do Microsoft Threat Intelligence Collection. Execute sempre a versão mais recente do conjunto de regras, que inclui as atualizações de segurança mais recentes, melhorias de regras e correções.

O DRS (Conjunto de Regras Padrão) gerenciado pelo Azure é a última geração de conjuntos de regras no WAF do Azure, substituindo todas as versões anteriores do Conjunto de Regras Principais (CRS). Entre as versões do DRS, utilize sempre a versão mais recente disponível (DRS 2.2) para garantir que dispõe das proteções mais atualizadas.

Este artigo apresenta exemplos em PowerShell para atualizar a sua política WAF do Azure para o DRS 2.2 a partir do CRS 3.0, CRS 3.1, CRS 3.2 ou DRS 2.1.

Observação

Os trechos do PowerShell são apenas exemplos. Substitua todos os espaços reservados por valores do seu ambiente.

Pré-requisitos

Principais considerações ao atualizar

Ao atualizar sua versão do conjunto de regras do WAF do Azure, certifique-se de:

  • Preservar as personalizações existentes: transfere as substituições das ações das regras, as substituições do estado das regras (ativadas ou desativadas) e as exclusões.

  • Eliminar personalizações para regras removidas: não transferir sobrescrições ou exclusões para regras que já não existem no DRS 2.2. Transferir um override para uma regra que o DRS 2.2 não contém faz com que a atualização da política falhe com um erro como The override Rule '<id>' is unknown for RuleGroup '<group>'.

  • Tenha em conta a configuração base do Nível de Paranoia: o DRS 2.2 funciona, por predefinição, no Nível de Paranoia 1 (PL1), e todas as regras de PL2 estão desativadas por predefinição. No CRS 3.2 e DRS 2.1, as regras PL2 estavam ativas. Quaisquer regras PL2 que tenhas personalizado anteriormente estão desativadas por defeito no DRS 2.2 até as reativares explicitamente.

  • Validar novas regras em segurança: as regras recentemente adicionadas que estão ativadas por defeito (PL1) estão inicialmente configuradas para modo log, para que possa monitorizar o seu impacto e ajustá-las finamente antes de ativar o bloqueio.

Prepare seu ambiente e variáveis

  1. Defina o contexto para a subscrição selecionada, grupo de recursos e política WAF do Azure.

    Import-Module Az.Network
    Set-AzContext -SubscriptionId "<subscription_id>"
    $resourceGroupName = "<resource_group>"
    $wafPolicyName = "<policy_name>"
    
  2. Obtenha o objeto de política WAF e recupere suas definições. O conjunto de regras gerido atual pode ser do tipo CRS (OWASP) ou DRS (Microsoft_DefaultRuleSet).

    $wafPolicy = Get-AzApplicationGatewayFirewallPolicy `
        -Name $wafPolicyName `
        -ResourceGroupName $resourceGroupName
    
    $currentExclusions = $wafPolicy.ManagedRules.Exclusions
    $currentManagedRuleset = $wafPolicy.ManagedRules.ManagedRuleSets |
        Where-Object { $_.RuleSetType -eq "OWASP" -or $_.RuleSetType -eq "Microsoft_DefaultRuleSet" }
    $currentVersion = $currentManagedRuleset.RuleSetVersion
    

Preservar personalizações existentes

  1. Transfira uma substituição ou exclusão apenas se a regra ainda existir em DRS 2.2. A função seguinte valida um ID de regra contra o conjunto completo de regras DRS 2.2 e devolve $true qualquer regra que tenha sido removida (incluindo regras legadas e inativas como 920460, 942130, e 920250). A utilização de uma lista de permissões de IDs de regras válidos evita a manutenção individual de cada regra e impede que a atualização da política falhe devido a uma regra desconhecida.

    function Test-RuleIsRemovedFromDRS22 {
        param (
            [string]$RuleId,
            [string]$CurrentRulesetVersion  # Retained for compatibility; not used
        )
    
        # Complete set of rule IDs that exist in DRS 2.2.
        # Any override or exclusion for a rule NOT in this set is dropped during migration.
        $drs22RuleIds = @(
            "200002","200003",
            "911100",
            "920100","920120","920121","920160","920170","920171","920180","920181","920190","920200","920201","920210","920220","920230","920240","920260","920270","920271","920280","920290","920300","920310","920311","920320","920330","920340","920341","920350","920420","920430","920440","920450","920470","920480","920500","920530","920620",
            "921110","921120","921130","921140","921150","921151","921160","921190","921200","921422",
            "930100","930110","930120","930130",
            "931100","931110","931120","931130",
            "932100","932105","932110","932115","932120","932130","932140","932150","932160","932170","932171","932180",
            "933100","933110","933120","933130","933140","933150","933151","933160","933170","933180","933200","933210",
            "934100",
            "941100","941101","941110","941120","941130","941140","941150","941160","941170","941180","941190","941200","941210","941220","941230","941240","941250","941260","941270","941280","941290","941300","941310","941320","941330","941340","941350","941360","941370","941380",
            "942100","942110","942120","942140","942150","942160","942170","942180","942190","942200","942210","942220","942230","942240","942250","942260","942270","942280","942290","942300","942310","942320","942330","942340","942350","942360","942361","942370","942380","942390","942400","942410","942430","942440","942450","942470","942480","942500","942510",
            "943100","943110","943120",
            "944100","944110","944120","944130","944200","944210","944240","944250",
            "99005002","99005003","99005004","99005005","99005006",
            "99030001","99030002","99030003","99030004","99030005","99030006",
            "99031001","99031002","99031003","99031004","99031005","99031006",
            "99001001","99001002","99001003","99001004","99001005","99001006","99001007","99001008","99001009","99001010","99001011","99001012","99001013","99001014","99001015","99001016","99001017","99001018",
            "99032001","99032002"
        )
    
        return -not ($drs22RuleIds -contains $RuleId)
    }
    
  2. Ao criar novos objetos de substituição, use os nomes dos grupos do DRS 2.2. A função seguinte faz o mapeamento dos nomes dos grupos CRS antigos para grupos DRS. Os nomes dos grupos de origem do DRS que não estão no mapa (por exemplo, ao atualizar do DRS 2.1) são devolvidos inalterados:

    function Get-DrsRuleGroupName {
        param (
            [Parameter(Mandatory = $true)]
            [string]$SourceGroupName
        )
        $groupMap = @{
            "REQUEST-930-APPLICATION-ATTACK-LFI"             = "LFI"
            "REQUEST-931-APPLICATION-ATTACK-RFI"             = "RFI"
            "REQUEST-932-APPLICATION-ATTACK-RCE"             = "RCE"
            "REQUEST-933-APPLICATION-ATTACK-PHP"             = "PHP"
            "REQUEST-941-APPLICATION-ATTACK-XSS"             = "XSS"
            "REQUEST-942-APPLICATION-ATTACK-SQLI"            = "SQLI"
            "REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" = "FIX"
            "REQUEST-944-APPLICATION-ATTACK-JAVA"            = "JAVA"
            "REQUEST-921-PROTOCOL-ATTACK"                    = "PROTOCOL-ATTACK"
            "REQUEST-911-METHOD-ENFORCEMENT"                 = "METHOD-ENFORCEMENT"
            "REQUEST-920-PROTOCOL-ENFORCEMENT"               = "PROTOCOL-ENFORCEMENT"
            "REQUEST-913-SCANNER-DETECTION"                  = $null  # No direct mapping
            "Known-CVEs"                                     = "MS-ThreatIntel-CVEs"
            "General"                                        = "General"
        }
        if ($groupMap.ContainsKey($SourceGroupName)) {
            return $groupMap[$SourceGroupName]
        } else {
            return $SourceGroupName  # No known mapping; pass through (DRS source group names)
        }
    }
    
  3. Utilize o seguinte código PowerShell para definir as substituições das regras, duplicando as substituições da versão existente do conjunto de regras:

    $groupOverrides = @()
    foreach ($group in $currentManagedRuleset.RuleGroupOverrides) {
        $mappedGroupName = Get-DrsRuleGroupName $group.RuleGroupName
        if (-not $mappedGroupName) { continue }  # Skip groups with no DRS equivalent
        foreach ($existingRule in $group.Rules) {
            if (-not (Test-RuleIsRemovedFromDRS22 $existingRule.RuleId $currentVersion)) {
                $existingGroup = $groupOverrides | Where-Object { $_.RuleGroupName -eq $mappedGroupName }
                if ($existingGroup) {
                    if (-not ($existingGroup.Rules | Where-Object { $_.RuleId -eq $existingRule.RuleId })) {
                        $existingGroup.Rules.Add($existingRule)
                    }
                } else {
                    $newGroup = New-AzApplicationGatewayFirewallPolicyManagedRuleGroupOverride `
                        -RuleGroupName $mappedGroupName `
                        -Rule @($existingRule)
                    $groupOverrides += $newGroup
                }
            }
        }
    }
    
  4. Use o seguinte código PowerShell para duplicar as suas exclusões existentes e aplicá-las no DRS 2.2:

    # Create new exclusion objects
    $newRuleSetExclusions = @()
    
    if ($currentExclusions -ne $null -and $currentExclusions.Count -gt 0) {
        foreach ($exclusion in $currentExclusions) {
            $newExclusion = New-AzApplicationGatewayFirewallPolicyExclusion `
                -MatchVariable $exclusion.MatchVariable `
                -SelectorMatchOperator $exclusion.SelectorMatchOperator `
                -Selector $exclusion.Selector
    
            # Migrate scopes: RuleSet, RuleGroup, or individual Rules
            if ($exclusion.ExclusionManagedRuleSets) {
                foreach ($scope in $exclusion.ExclusionManagedRuleSets) {
                    # Create RuleGroup objects from existing RuleGroups
                    $ruleGroups = @()
                    foreach ($group in $scope.RuleGroups) {
                        $drsGroupName = Get-DrsRuleGroupName $group.RuleGroupName
                        if ($drsGroupName) {
                            $exclusionRules = @()
                            foreach ($rule in $group.Rules) {
                                if (-not (Test-RuleIsRemovedFromDRS22 $rule.RuleId $currentVersion)) {
                                    $exclusionRules += New-AzApplicationGatewayFirewallPolicyExclusionManagedRule `
                                        -RuleId $rule.RuleId
                                }
                            }
                            if ($exclusionRules -ne $null -and $exclusionRules.Count -gt 0) {
                                $ruleGroups += New-AzApplicationGatewayFirewallPolicyExclusionManagedRuleGroup `
                                    -Name $drsGroupName `
                                    -Rule $exclusionRules
                            } else {
                                $ruleGroups += New-AzApplicationGatewayFirewallPolicyExclusionManagedRuleGroup `
                                    -Name $drsGroupName
                            }
                        }
                    }
    
                    # Create the ManagedRuleSet scope object with the updated RuleGroups
                    if ($ruleGroups.Count -gt 0) {
                        $newRuleSetScope = New-AzApplicationGatewayFirewallPolicyExclusionManagedRuleSet `
                            -Type "Microsoft_DefaultRuleSet" `
                            -Version "2.2" `
                            -RuleGroup $ruleGroups
    
                        # Add to the new exclusion object
                        $newExclusion.ExclusionManagedRuleSets += $newRuleSetScope
                    }
                }
            }
    
            if (-not $newExclusion.ExclusionManagedRuleSets) {
                $newExclusion.ExclusionManagedRuleSets = @()
            }
    
            $newRuleSetExclusions += $newExclusion
        }
    }
    

Valide novas regras com segurança

Quando atualizas, as novas regras do DRS 2.2 que pertencem ao Paranoia Nível 1 são ativadas por defeito. Se o seu WAF estiver em modo de Prevenção , defina estas novas regras para o modo log primeiro para poder rever os logs antes de ativar o bloqueio.

Regras que pertencem ao Paranoia Nível 2 estão desativadas por defeito no DRS 2.2 e não bloqueiam o tráfego, por isso não exigem este passo. Se quiseres operar no Paranoia Nível 2, ativa explicitamente as regras relevantes de PL2 e segue a mesma abordagem de validação em log.

  1. Utilize a definição que corresponde à versão a partir da qual está a atualizar . Cada definição lista as regras que são introduzidas e ativadas por defeito no DRS 2.2 em comparação com essa versão.

    # Added and enabled by default in DRS 2.2 compared to CRS 3.0
    $rulesAddedInThisVersionByGroup = @{
        "General"              = @("200002", "200003")
        "PROTOCOL-ENFORCEMENT" = @("920171", "920181", "920470", "920480", "920500", "920530", "920620")
        "PROTOCOL-ATTACK"      = @("921190", "921200")
        "RCE"                  = @("932180")
        "PHP"                  = @("933200", "933210")
        "NODEJS"               = @("934100")
        "XSS"                  = @("941360", "941370")
        "SQLI"                 = @("942500")
        "JAVA"                 = @("944100", "944110", "944120", "944130")
        "MS-ThreatIntel-CVEs"  = @("99001018")
        "MS-ThreatIntel-XSS"   = @("99032001")
    }
    
    # Added and enabled by default in DRS 2.2 compared to CRS 3.1
    $rulesAddedInThisVersionByGroup = @{
        "General"              = @("200002", "200003")
        "PROTOCOL-ENFORCEMENT" = @("920181", "920500", "920530", "920620")
        "PROTOCOL-ATTACK"      = @("921190", "921200")
        "PHP"                  = @("933200", "933210")
        "NODEJS"               = @("934100")
        "XSS"                  = @("941360", "941370")
        "SQLI"                 = @("942500")
        "MS-ThreatIntel-CVEs"  = @("99001018")
        "MS-ThreatIntel-XSS"   = @("99032001")
    }
    
    # Added and enabled by default in DRS 2.2 compared to CRS 3.2
    $rulesAddedInThisVersionByGroup = @{
        "PROTOCOL-ENFORCEMENT" = @("920181", "920500", "920530", "920620")
        "PROTOCOL-ATTACK"      = @("921190", "921200")
        "NODEJS"               = @("934100")
        "XSS"                  = @("941370")
        "MS-ThreatIntel-CVEs"  = @("99001018")
        "MS-ThreatIntel-XSS"   = @("99032001")
    }
    
    # Added and enabled by default in DRS 2.2 compared to DRS 2.1
    $rulesAddedInThisVersionByGroup = @{
        "PROTOCOL-ENFORCEMENT" = @("920530", "920620")
        "MS-ThreatIntel-XSS"   = @("99032001")
    }
    
  2. Use o seguinte código PowerShell para adicionar os novos overrides de regras ao objeto existente $groupOverrides definido anteriormente:

    foreach ($groupName in $rulesAddedInThisVersionByGroup.Keys) {
        $ruleOverrides = @()
        foreach ($ruleId in $rulesAddedInThisVersionByGroup[$groupName]) {
            $existingGroup = $groupOverrides | Where-Object { $_.RuleGroupName -eq $groupName }
            $alreadyExists = $false
            if ($existingGroup) {
                $alreadyExists = $existingGroup.Rules | Where-Object { $_.RuleId -eq $ruleId }
            }
            if (-not $alreadyExists) {
                $ruleOverrides += New-AzApplicationGatewayFirewallPolicyManagedRuleOverride `
                    -RuleId $ruleId `
                    -Action "Log" `
                    -State "Enabled"
            }
        }
        # Only create or update the group override if we added rules to it
        if ($ruleOverrides.Count -gt 0) {
            $existingGroup = $groupOverrides | Where-Object { $_.RuleGroupName -eq $groupName }
            if ($existingGroup) {
                foreach ($ruleOverride in $ruleOverrides) {
                    $existingGroup.Rules.Add($ruleOverride)
                }
            } else {
                $groupOverrides += New-AzApplicationGatewayFirewallPolicyManagedRuleGroupOverride `
                    -RuleGroupName $groupName `
                    -Rule $ruleOverrides
            }
        }
    }
    

Aplicar personalizações e atualizar

Defina seu objeto de política WAF do Azure atualizado, incorporando as substituições e exclusões de regras duplicadas e atualizadas:

$managedRuleSet = New-AzApplicationGatewayFirewallPolicyManagedRuleSet `
    -RuleSetType "Microsoft_DefaultRuleSet" `
    -RuleSetVersion "2.2" `
    -RuleGroupOverride $groupOverrides

# Replace the existing CRS (OWASP) or DRS (Microsoft_DefaultRuleSet) managed rule set
for ($i = 0; $i -lt $wafPolicy.ManagedRules.ManagedRuleSets.Count; $i++) {
    if ($wafPolicy.ManagedRules.ManagedRuleSets[$i].RuleSetType -eq "OWASP" -or
        $wafPolicy.ManagedRules.ManagedRuleSets[$i].RuleSetType -eq "Microsoft_DefaultRuleSet") {
        $wafPolicy.ManagedRules.ManagedRuleSets[$i] = $managedRuleSet
        break
    }
}

# Assign the migrated exclusions to the policy
$wafPolicy.ManagedRules.Exclusions = $newRuleSetExclusions

# Apply the updated WAF policy
Set-AzApplicationGatewayFirewallPolicy -InputObject $wafPolicy