Skip to content

Commit

Permalink
azurerm_web_application_firewall_policy - fix failure caused by ord…
Browse files Browse the repository at this point in the history
…er change of `disabled_rules` (#20285)

fix #20183
  • Loading branch information
ms-zhenhua authored Feb 6, 2023
1 parent 80b775b commit 059cb69
Show file tree
Hide file tree
Showing 2 changed files with 231 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -438,12 +438,17 @@ func resourceWebApplicationFirewallPolicyCreateUpdate(d *pluginsdk.ResourceData,
managedRules := d.Get("managed_rules").([]interface{})
t := d.Get("tags").(map[string]interface{})

expandedManagedRules, err := expandWebApplicationFirewallPolicyManagedRulesDefinition(managedRules, d)
if err != nil {
return err
}

parameters := network.WebApplicationFirewallPolicy{
Location: utils.String(location),
WebApplicationFirewallPolicyPropertiesFormat: &network.WebApplicationFirewallPolicyPropertiesFormat{
CustomRules: expandWebApplicationFirewallPolicyWebApplicationFirewallCustomRule(customRules),
PolicySettings: expandWebApplicationFirewallPolicyPolicySettings(policySettings),
ManagedRules: expandWebApplicationFirewallPolicyManagedRulesDefinition(managedRules),
ManagedRules: expandedManagedRules,
},
Tags: tags.Expand(t),
}
Expand Down Expand Up @@ -573,19 +578,24 @@ func expandWebApplicationFirewallPolicyPolicySettings(input []interface{}) *netw
return &result
}

func expandWebApplicationFirewallPolicyManagedRulesDefinition(input []interface{}) *network.ManagedRulesDefinition {
func expandWebApplicationFirewallPolicyManagedRulesDefinition(input []interface{}, d *pluginsdk.ResourceData) (*network.ManagedRulesDefinition, error) {
if len(input) == 0 {
return nil
return nil, nil
}
v := input[0].(map[string]interface{})

exclusions := v["exclusion"].([]interface{})
managedRuleSets := v["managed_rule_set"].([]interface{})

expandedManagedRuleSets, err := expandWebApplicationFirewallPolicyManagedRuleSet(managedRuleSets, d)
if err != nil {
return nil, err
}

return &network.ManagedRulesDefinition{
Exclusions: expandWebApplicationFirewallPolicyExclusions(exclusions),
ManagedRuleSets: expandWebApplicationFirewallPolicyManagedRuleSet(managedRuleSets),
}
ManagedRuleSets: expandedManagedRuleSets,
}, nil
}

func expandWebApplicationFirewallPolicyExclusionManagedRules(input []interface{}) *[]network.ExclusionManagedRule {
Expand Down Expand Up @@ -666,31 +676,37 @@ func expandWebApplicationFirewallPolicyExclusions(input []interface{}) *[]networ
return &results
}

func expandWebApplicationFirewallPolicyManagedRuleSet(input []interface{}) *[]network.ManagedRuleSet {
func expandWebApplicationFirewallPolicyManagedRuleSet(input []interface{}, d *pluginsdk.ResourceData) (*[]network.ManagedRuleSet, error) {
results := make([]network.ManagedRuleSet, 0)
for _, item := range input {
v := item.(map[string]interface{})

for i, item := range input {
v := item.(map[string]interface{})
ruleSetType := v["type"].(string)
ruleSetVersion := v["version"].(string)
ruleGroupOverrides := []interface{}{}
if value, exists := v["rule_group_override"]; exists {
ruleGroupOverrides = value.([]interface{})
}

expandedRuleGroupOverrides, err := expandWebApplicationFirewallPolicyRuleGroupOverrides(ruleGroupOverrides, d, i)
if err != nil {
return nil, err
}

result := network.ManagedRuleSet{
RuleSetType: utils.String(ruleSetType),
RuleSetVersion: utils.String(ruleSetVersion),
RuleGroupOverrides: expandWebApplicationFirewallPolicyRuleGroupOverrides(ruleGroupOverrides),
RuleGroupOverrides: expandedRuleGroupOverrides,
}

results = append(results, result)
}
return &results
return &results, nil
}

func expandWebApplicationFirewallPolicyRuleGroupOverrides(input []interface{}) *[]network.ManagedRuleGroupOverride {
func expandWebApplicationFirewallPolicyRuleGroupOverrides(input []interface{}, d *pluginsdk.ResourceData, managedRuleSetIndex int) (*[]network.ManagedRuleGroupOverride, error) {
results := make([]network.ManagedRuleGroupOverride, 0)
for _, item := range input {
for i, item := range input {
v := item.(map[string]interface{})

ruleGroupName := v["rule_group_name"].(string)
Expand All @@ -700,19 +716,35 @@ func expandWebApplicationFirewallPolicyRuleGroupOverrides(input []interface{}) *
}

if !features.FourPointOhBeta() {
if disabledRules := v["disabled_rules"].([]interface{}); len(disabledRules) > 0 {
// `disabled_rules` will be deprecated from 4.0. In 3.x, `rule` and `disabled_rules` point to the same properties of Azure REST API and conflict with each other in the configuration.
// Since both properties will be set in the flatten method, need to use `GetRawConfig` to check which one of these two properties is configured in the configuration file.
managedRuleSetList := d.GetRawConfig().AsValueMap()["managed_rules"].AsValueSlice()[0].AsValueMap()["managed_rule_set"].AsValueSlice()
if managedRuleSetIndex >= len(managedRuleSetList) {
return nil, fmt.Errorf("managed rule set index %d exceeds raw config length %d", managedRuleSetIndex, len(managedRuleSetList))
}

ruleGroupOverrideList := managedRuleSetList[managedRuleSetIndex].AsValueMap()["rule_group_override"].AsValueSlice()
if i >= len(ruleGroupOverrideList) {
return nil, fmt.Errorf("rule group override index %d exceeds raw config length %d", i, len(ruleGroupOverrideList))
}

if disabledRules := v["disabled_rules"].([]interface{}); !ruleGroupOverrideList[i].AsValueMap()["disabled_rules"].IsNull() {
result.Rules = expandWebApplicationFirewallPolicyRules(disabledRules)
}
}

if rules := v["rule"].([]interface{}); len(rules) > 0 {
result.Rules = expandWebApplicationFirewallPolicyOverrideRules(rules)
if rules := v["rule"].([]interface{}); !ruleGroupOverrideList[i].AsValueMap()["rule"].IsNull() && len(ruleGroupOverrideList[i].AsValueMap()["rule"].AsValueSlice()) > 0 {
result.Rules = expandWebApplicationFirewallPolicyOverrideRules(rules)
}
} else {
if rules := v["rule"].([]interface{}); len(rules) > 0 {
result.Rules = expandWebApplicationFirewallPolicyOverrideRules(rules)
}
}

results = append(results, result)
}

return &results
return &results, nil
}

func expandWebApplicationFirewallPolicyRules(input []interface{}) *[]network.ManagedRuleOverride {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,28 @@ func TestAccWebApplicationFirewallPolicy_excludedRules(t *testing.T) {
})
}

func TestAccWebApplicationFirewallPolicy_updateDisabledRules(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_web_application_firewall_policy", "test")
r := WebApplicationFirewallResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.disabledRules(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
{
Config: r.updateDisabledRules(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func (t WebApplicationFirewallResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := parse.ApplicationGatewayWebApplicationFirewallPolicyID(state.ID)
if err != nil {
Expand Down Expand Up @@ -489,6 +511,12 @@ resource "azurerm_web_application_firewall_policy" "test" {
rule_group_override {
rule_group_name = "REQUEST-920-PROTOCOL-ENFORCEMENT"
rule {
id = "920440"
enabled = true
action = "Block"
}
}
}
}
Expand Down Expand Up @@ -771,3 +799,157 @@ resource "azurerm_web_application_firewall_policy" "test" {
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (WebApplicationFirewallResource) disabledRules(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}
resource "azurerm_web_application_firewall_policy" "test" {
name = "acctestwafpolicy-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
policy_settings {
enabled = true
mode = "Prevention"
request_body_check = true
file_upload_limit_in_mb = 100
max_request_body_size_in_kb = 2000
}
managed_rules {
managed_rule_set {
type = "OWASP"
version = "3.2"
rule_group_override {
rule_group_name = "REQUEST-931-APPLICATION-ATTACK-RFI"
disabled_rules = ["931130"]
}
rule_group_override {
rule_group_name = "REQUEST-920-PROTOCOL-ENFORCEMENT"
disabled_rules = [
"920320", # Missing User Agent Header
"920230" # Multiple URL Encoding Detected
]
}
rule_group_override {
rule_group_name = "REQUEST-942-APPLICATION-ATTACK-SQLI"
disabled_rules = [
"942450",
"942430",
"942440",
"942370",
"942340",
"942260",
"942200",
"942330",
"942120",
"942110",
"942150",
"942410",
"942130",
"942100"
]
}
rule_group_override {
rule_group_name = "REQUEST-941-APPLICATION-ATTACK-XSS"
disabled_rules = [
"941340"
]
}
}
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (WebApplicationFirewallResource) updateDisabledRules(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}
resource "azurerm_web_application_firewall_policy" "test" {
name = "acctestwafpolicy-%d"
resource_group_name = azurerm_resource_group.test.name
location = azurerm_resource_group.test.location
policy_settings {
enabled = true
mode = "Prevention"
request_body_check = true
file_upload_limit_in_mb = 100
max_request_body_size_in_kb = 2000
}
managed_rules {
managed_rule_set {
type = "OWASP"
version = "3.2"
rule_group_override {
rule_group_name = "REQUEST-931-APPLICATION-ATTACK-RFI"
disabled_rules = ["931130"]
}
rule_group_override {
rule_group_name = "REQUEST-920-PROTOCOL-ENFORCEMENT"
disabled_rules = [
"920320", # Missing User Agent Header
"920230" # Multiple URL Encoding Detected
]
}
#NEW BLOCK
rule_group_override {
rule_group_name = "REQUEST-932-APPLICATION-ATTACK-RCE"
disabled_rules = ["932100"]
}
rule_group_override {
rule_group_name = "REQUEST-942-APPLICATION-ATTACK-SQLI"
disabled_rules = [
"942450",
"942430",
"942440",
"942370",
"942340",
"942260",
"942200",
"942330",
"942120",
"942110",
"942150",
"942410",
"942130",
"942100"
]
}
rule_group_override {
rule_group_name = "REQUEST-941-APPLICATION-ATTACK-XSS"
disabled_rules = [
"941340"
]
}
}
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

0 comments on commit 059cb69

Please sign in to comment.