From 80c97f27a7504319632fcb7641afb136590f8f6e Mon Sep 17 00:00:00 2001 From: rtrompier Date: Thu, 12 Oct 2023 17:15:48 +0200 Subject: [PATCH 1/3] feat(wafv2_web_acl): add ACFP rule support --- internal/service/wafv2/flex.go | 106 ++++++++ internal/service/wafv2/schemas.go | 99 ++++++++ internal/service/wafv2/web_acl_test.go | 226 ++++++++++++++++++ .../python/r/wafv2_web_acl.html.markdown | 9 + .../typescript/r/wafv2_web_acl.html.markdown | 9 + website/docs/r/wafv2_web_acl.html.markdown | 81 +++++++ 6 files changed, 530 insertions(+) diff --git a/internal/service/wafv2/flex.go b/internal/service/wafv2/flex.go index b80ee4f02ab..eec40db1d9a 100644 --- a/internal/service/wafv2/flex.go +++ b/internal/service/wafv2/flex.go @@ -1099,6 +1099,9 @@ func expandManagedRuleGroupConfigs(tfList []interface{}) []*wafv2.ManagedRuleGro if v, ok := m["aws_managed_rules_bot_control_rule_set"].([]interface{}); ok && len(v) > 0 { r.AWSManagedRulesBotControlRuleSet = expandManagedRulesBotControlRuleSet(v) } + if v, ok := m["aws_managed_rules_acfp_rule_set"].([]interface{}); ok && len(v) > 0 { + r.AWSManagedRulesACFPRuleSet = expandManagedRulesACFPRuleSet(v) + } if v, ok := m["aws_managed_rules_atp_rule_set"].([]interface{}); ok && len(v) > 0 { r.AWSManagedRulesATPRuleSet = expandManagedRulesATPRuleSet(v) } @@ -1121,6 +1124,19 @@ func expandManagedRuleGroupConfigs(tfList []interface{}) []*wafv2.ManagedRuleGro return out } +func expandEmailField(tfList []interface{}) *wafv2.EmailField { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + m := tfList[0].(map[string]interface{}) + out := wafv2.EmailField{ + Identifier: aws.String(m["identifier"].(string)), + } + + return &out +} + func expandPasswordField(tfList []interface{}) *wafv2.PasswordField { if len(tfList) == 0 || tfList[0] == nil { return nil @@ -1160,6 +1176,30 @@ func expandManagedRulesBotControlRuleSet(tfList []interface{}) *wafv2.AWSManaged return &out } +func expandManagedRulesACFPRuleSet(tfList []interface{}) *wafv2.AWSManagedRulesACFPRuleSet { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + m := tfList[0].(map[string]interface{}) + out := wafv2.AWSManagedRulesACFPRuleSet{ + CreationPath: aws.String(m["creation_path"].(string)), + RegistrationPagePath: aws.String(m["registration_page_path"].(string)), + } + + if v, ok := m["enable_regex_in_path"].(bool); ok { + out.EnableRegexInPath = aws.Bool(v) + } + if v, ok := m["request_inspection"].([]interface{}); ok && len(v) > 0 { + out.RequestInspection = expandRequestInspectionACFP(v) + } + if v, ok := m["response_inspection"].([]interface{}); ok && len(v) > 0 { + out.ResponseInspection = expandResponseInspection(v) + } + + return &out +} + func expandManagedRulesATPRuleSet(tfList []interface{}) *wafv2.AWSManagedRulesATPRuleSet { if len(tfList) == 0 || tfList[0] == nil { return nil @@ -1198,6 +1238,22 @@ func expandRequestInspection(tfList []interface{}) *wafv2.RequestInspection { return &out } +func expandRequestInspectionACFP(tfList []interface{}) *wafv2.RequestInspectionACFP { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + m := tfList[0].(map[string]interface{}) + out := wafv2.RequestInspectionACFP{ + EmailField: expandEmailField(m["email_field"].([]interface{})), + PasswordField: expandPasswordField(m["password_field"].([]interface{})), + PayloadType: aws.String(m["payload_type"].(string)), + UsernameField: expandUsernameField(m["username_field"].([]interface{})), + } + + return &out +} + func expandResponseInspection(tfList []interface{}) *wafv2.ResponseInspection { if len(tfList) == 0 || tfList[0] == nil { return nil @@ -2365,6 +2421,9 @@ func flattenManagedRuleGroupConfigs(c []*wafv2.ManagedRuleGroupConfig) []interfa for _, config := range c { m := make(map[string]interface{}) + if config.AWSManagedRulesACFPRuleSet != nil { + m["aws_managed_rules_acfp_rule_set"] = flattenManagedRulesACFPRuleSet(config.AWSManagedRulesACFPRuleSet) + } if config.AWSManagedRulesBotControlRuleSet != nil { m["aws_managed_rules_bot_control_rule_set"] = flattenManagedRulesBotControlRuleSet(config.AWSManagedRulesBotControlRuleSet) } @@ -2390,6 +2449,18 @@ func flattenManagedRuleGroupConfigs(c []*wafv2.ManagedRuleGroupConfig) []interfa return out } +func flattenEmailField(apiObject *wafv2.EmailField) []interface{} { + if apiObject == nil { + return nil + } + + m := map[string]interface{}{ + "identifier": aws.StringValue(apiObject.Identifier), + } + + return []interface{}{m} +} + func flattenPasswordField(apiObject *wafv2.PasswordField) []interface{} { if apiObject == nil { return nil @@ -2426,6 +2497,26 @@ func flattenManagedRulesBotControlRuleSet(apiObject *wafv2.AWSManagedRulesBotCon return []interface{}{m} } +func flattenManagedRulesACFPRuleSet(apiObject *wafv2.AWSManagedRulesACFPRuleSet) []interface{} { + if apiObject == nil { + return nil + } + + m := map[string]interface{}{ + "enable_regex_in_path": aws.BoolValue(apiObject.EnableRegexInPath), + "creation_path": aws.StringValue(apiObject.CreationPath), + "registration_page_path": aws.StringValue(apiObject.RegistrationPagePath), + } + if apiObject.RequestInspection != nil { + m["request_inspection"] = flattenRequestInspectionACFP(apiObject.RequestInspection) + } + if apiObject.ResponseInspection != nil { + m["response_inspection"] = flattenResponseInspection(apiObject.ResponseInspection) + } + + return []interface{}{m} +} + func flattenManagedRulesATPRuleSet(apiObject *wafv2.AWSManagedRulesATPRuleSet) []interface{} { if apiObject == nil { return nil @@ -2445,6 +2536,21 @@ func flattenManagedRulesATPRuleSet(apiObject *wafv2.AWSManagedRulesATPRuleSet) [ return []interface{}{m} } +func flattenRequestInspectionACFP(apiObject *wafv2.RequestInspectionACFP) []interface{} { + if apiObject == nil { + return nil + } + + m := map[string]interface{}{ + "email_field": flattenEmailField(apiObject.EmailField), + "password_field": flattenPasswordField(apiObject.PasswordField), + "payload_type": aws.StringValue(apiObject.PayloadType), + "username_field": flattenUsernameField(apiObject.UsernameField), + } + + return []interface{}{m} +} + func flattenRequestInspection(apiObject *wafv2.RequestInspection) []interface{} { if apiObject == nil { return nil diff --git a/internal/service/wafv2/schemas.go b/internal/service/wafv2/schemas.go index 107e236d8a8..652fb6fd334 100644 --- a/internal/service/wafv2/schemas.go +++ b/internal/service/wafv2/schemas.go @@ -1094,6 +1094,37 @@ func managedRuleGroupConfigSchema() *schema.Schema { Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "aws_managed_rules_acfp_rule_set": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enable_regex_in_path": { + Type: schema.TypeBool, + Optional: true, + }, + "creation_path": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 256), + validation.StringMatch(regexache.MustCompile(`.*\S.*`), `must conform to pattern .*\S.* `), + ), + }, + "registration_page_path": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 256), + validation.StringMatch(regexache.MustCompile(`.*\S.*`), `must conform to pattern .*\S.* `), + ), + }, + "request_inspection": managedRuleGroupConfigACFPRequestInspectionSchema(), + "response_inspection": managedRuleGroupConfigATPResponseInspectionSchema(), + }, + }, + }, "aws_managed_rules_atp_rule_set": { Type: schema.TypeList, Optional: true, @@ -1218,6 +1249,74 @@ func ruleGroupReferenceStatementSchema() *schema.Schema { } } +func managedRuleGroupConfigACFPRequestInspectionSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "email_field": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "identifier": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 512), + validation.StringMatch(regexache.MustCompile(`.*\S.*`), `must conform to pattern .*\S.* `), + ), + }, + }, + }, + }, + "password_field": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "identifier": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 512), + validation.StringMatch(regexache.MustCompile(`.*\S.*`), `must conform to pattern .*\S.* `), + ), + }, + }, + }, + }, + "payload_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(wafv2.PayloadType_Values(), false), + }, + "username_field": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "identifier": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.All( + validation.StringLenBetween(1, 512), + validation.StringMatch(regexache.MustCompile(`.*\S.*`), `must conform to pattern .*\S.* `), + ), + }, + }, + }, + }, + }, + }, + } +} + func managedRuleGroupConfigATPRequestInspectionSchema() *schema.Schema { return &schema.Schema{ Type: schema.TypeList, diff --git a/internal/service/wafv2/web_acl_test.go b/internal/service/wafv2/web_acl_test.go index a7d25064fc2..804559e88ef 100644 --- a/internal/service/wafv2/web_acl_test.go +++ b/internal/service/wafv2/web_acl_test.go @@ -708,6 +708,98 @@ func TestAccWAFV2WebACL_ManagedRuleGroup_ManagedRuleGroupConfig(t *testing.T) { }) } +func TestAccWAFV2WebACL_ManagedRuleGroup_ManagedRuleGroupConfig_ACFPRuleSet(t *testing.T) { + ctx := acctest.Context(t) + var v wafv2.WebACL + webACLName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_wafv2_web_acl.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheckScopeRegional(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, wafv2.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckWebACLDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccWebACLConfig_managedRuleGroupStatementManagedRuleGroupConfig_acfpRuleSet(webACLName), + Check: resource.ComposeTestCheckFunc( + testAccCheckWebACLExists(ctx, resourceName, &v), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexache.MustCompile(`regional/webacl/.+$`)), + resource.TestCheckResourceAttr(resourceName, "name", webACLName), + resource.TestCheckResourceAttr(resourceName, "rule.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{ + "name": "rule-1", + "action.#": "0", + "override_action.#": "1", + "override_action.0.count.#": "0", + "override_action.0.none.#": "1", + "statement.#": "1", + "statement.0.managed_rule_group_statement.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.#": "1", + // "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.enable_regex_in_path": "false", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.creation_path": "/creation", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.registration_page_path": "/registration", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.email_field.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.email_field.0.identifier": "/email", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.password_field.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.password_field.0.identifier": "/password", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.payload_type": "JSON", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.username_field.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.username_field.0.identifier": "/username", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.response_inspection.#": "0", + "statement.0.managed_rule_group_statement.0.name": "AWSManagedRulesACFPRuleSet", + "statement.0.managed_rule_group_statement.0.rule_action_override.#": "0", + "statement.0.managed_rule_group_statement.0.scope_down_statement.#": "0", + "statement.0.managed_rule_group_statement.0.vendor_name": "AWS", + }), + ), + }, + { + Config: testAccWebACLConfig_managedRuleGroupStatementManagedRuleGroupConfig_acfpRuleSetUpdate(webACLName), + Check: resource.ComposeTestCheckFunc( + testAccCheckWebACLExists(ctx, resourceName, &v), + acctest.MatchResourceAttrRegionalARN(resourceName, "arn", "wafv2", regexache.MustCompile(`regional/webacl/.+$`)), + resource.TestCheckResourceAttr(resourceName, "name", webACLName), + resource.TestCheckResourceAttr(resourceName, "rule.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "rule.*", map[string]string{ + "name": "rule-1", + "action.#": "0", + "override_action.#": "1", + "override_action.0.count.#": "0", + "override_action.0.none.#": "1", + "statement.#": "1", + "statement.0.managed_rule_group_statement.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.enable_regex_in_path": "true", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.creation_path": "/creation", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.registration_page_path": "/registration", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.email_field.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.email_field.0.identifier": "/email", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.password_field.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.password_field.0.identifier": "/pass", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.payload_type": "JSON", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.username_field.#": "1", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.request_inspection.0.username_field.0.identifier": "/user", + "statement.0.managed_rule_group_statement.0.managed_rule_group_configs.0.aws_managed_rules_acfp_rule_set.0.response_inspection.#": "0", + "statement.0.managed_rule_group_statement.0.name": "AWSManagedRulesACFPRuleSet", + "statement.0.managed_rule_group_statement.0.rule_action_override.#": "0", + "statement.0.managed_rule_group_statement.0.scope_down_statement.#": "0", + "statement.0.managed_rule_group_statement.0.vendor_name": "AWS", + }), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateIdFunc: testAccWebACLImportStateIdFunc(resourceName), + }, + }, + }) +} + func TestAccWAFV2WebACL_ManagedRuleGroup_ManagedRuleGroupConfig_ATPRuleSet(t *testing.T) { ctx := acctest.Context(t) var v wafv2.WebACL @@ -3913,6 +4005,72 @@ resource "aws_wafv2_web_acl" "test" { `, rName) } +func testAccWebACLConfig_managedRuleGroupStatementManagedRuleGroupConfig_acfpRuleSet(rName string) string { + return fmt.Sprintf(` +resource "aws_wafv2_web_acl" "test" { + name = %[1]q + description = %[1]q + scope = "REGIONAL" + + default_action { + allow {} + } + + rule { + name = "rule-1" + priority = 1 + + override_action { + none {} + } + + statement { + managed_rule_group_statement { + name = "AWSManagedRulesACFPRuleSet" + vendor_name = "AWS" + + managed_rule_group_configs { + aws_managed_rules_acfp_rule_set { + creation_path = "/creation" + registration_page_path = "/registration" + request_inspection { + email_field { + identifier = "/email" + } + password_field { + identifier = "/password" + } + payload_type = "JSON" + username_field { + identifier = "/username" + } + } + } + } + } + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "friendly-rule-metric-name" + sampled_requests_enabled = false + } + } + + tags = { + Tag1 = "Value1" + Tag2 = "Value2" + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "friendly-metric-name" + sampled_requests_enabled = false + } +} +`, rName) +} + func testAccWebACLConfig_managedRuleGroupStatementManagedRuleGroupConfig_atpRuleSet(rName string) string { return fmt.Sprintf(` resource "aws_wafv2_web_acl" "test" { @@ -3975,6 +4133,74 @@ resource "aws_wafv2_web_acl" "test" { `, rName) } +func testAccWebACLConfig_managedRuleGroupStatementManagedRuleGroupConfig_acfpRuleSetUpdate(rName string) string { + return fmt.Sprintf(` +resource "aws_wafv2_web_acl" "test" { + name = %[1]q + description = %[1]q + scope = "REGIONAL" + + default_action { + allow {} + } + + rule { + name = "rule-1" + priority = 1 + + override_action { + none {} + } + + statement { + managed_rule_group_statement { + name = "AWSManagedRulesACFPRuleSet" + vendor_name = "AWS" + + managed_rule_group_configs { + aws_managed_rules_acfp_rule_set { + enable_regex_in_path = true + creation_path = "/creation" + registration_page_path = "/registration" + + request_inspection { + email_field { + identifier = "/email" + } + password_field { + identifier = "/pass" + } + payload_type = "JSON" + username_field { + identifier = "/user" + } + } + } + } + } + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "friendly-rule-metric-name" + sampled_requests_enabled = false + } + } + + tags = { + Tag1 = "Value1" + Tag2 = "Value2" + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "friendly-metric-name" + sampled_requests_enabled = false + } +} +`, rName) +} + func testAccWebACLConfig_managedRuleGroupStatementManagedRuleGroupConfig_atpRuleSetUpdate(rName string) string { return fmt.Sprintf(` resource "aws_wafv2_web_acl" "test" { diff --git a/website/docs/cdktf/python/r/wafv2_web_acl.html.markdown b/website/docs/cdktf/python/r/wafv2_web_acl.html.markdown index 90bd6aede16..16e23027713 100644 --- a/website/docs/cdktf/python/r/wafv2_web_acl.html.markdown +++ b/website/docs/cdktf/python/r/wafv2_web_acl.html.markdown @@ -661,6 +661,7 @@ The `rule_action_override` block supports the following arguments: The `managed_rule_group_configs` block support the following arguments: * `aws_managed_rules_bot_control_rule_set` - (Optional) Additional configuration for using the Bot Control managed rule group. Use this to specify the inspection level that you want to use. See [`aws_managed_rules_bot_control_rule_set`](#aws_managed_rules_bot_control_rule_set-block) for more details +* `aws_managed_rules_acfp_rule_set` - (Optional) Additional configuration for using the Account Creation Fraud Prevention managed rule group. Use this to specify information such as the registration page of your application and the type of content to accept or reject from the client. * `aws_managed_rules_atp_rule_set` - (Optional) Additional configuration for using the Account Takeover Protection managed rule group. Use this to specify information such as the sign-in page of your application and the type of content to accept or reject from the client. * `login_path` - (Optional, **Deprecated**) The path of the login endpoint for your application. * `password_field` - (Optional, **Deprecated**) Details about your login page password field. See [`password_field`](#password_field-block) for more details. @@ -671,6 +672,14 @@ The `managed_rule_group_configs` block support the following arguments: * `inspection_level` - (Optional) The inspection level to use for the Bot Control rule group. +### `aws_managed_rules_acfp_rule_set` Block + +* `creation_path` - (Required) The path of the account creation endpoint for your application. This is the page on your website that accepts the completed registration form for a new user. This page must accept POST requests. +* `enable_regex_in_path` - (Optional) Whether or not to allow the use of regular expressions in the login page path. +* `registration_page_path` - (Required) The path of the account registration endpoint for your application. This is the page on your website that presents the registration form to new users. This page must accept GET text/html requests. +* `request_inspection` - (Optional) The criteria for inspecting login requests, used by the ATP rule group to validate credentials usage. See [`request_inspection`](#request_inspection-block) for more details. +* `response_inspection` - (Optional) The criteria for inspecting responses to login requests, used by the ATP rule group to track login failure rates. Note that Response Inspection is available only on web ACLs that protect CloudFront distributions. See [`response_inspection`](#response_inspection-block) for more details. + ### `aws_managed_rules_atp_rule_set` Block * `enable_regex_in_path` - (Optional) Whether or not to allow the use of regular expressions in the login page path. diff --git a/website/docs/cdktf/typescript/r/wafv2_web_acl.html.markdown b/website/docs/cdktf/typescript/r/wafv2_web_acl.html.markdown index 9193b5a1052..db774a8c3f8 100644 --- a/website/docs/cdktf/typescript/r/wafv2_web_acl.html.markdown +++ b/website/docs/cdktf/typescript/r/wafv2_web_acl.html.markdown @@ -685,6 +685,7 @@ The `ruleActionOverride` block supports the following arguments: The `managedRuleGroupConfigs` block support the following arguments: * `awsManagedRulesBotControlRuleSet` - (Optional) Additional configuration for using the Bot Control managed rule group. Use this to specify the inspection level that you want to use. See [`awsManagedRulesBotControlRuleSet`](#aws_managed_rules_bot_control_rule_set-block) for more details +* `aws_managed_rules_acfp_rule_set` - (Optional) Additional configuration for using the Account Creation Fraud Prevention managed rule group. Use this to specify information such as the registration page of your application and the type of content to accept or reject from the client. * `awsManagedRulesAtpRuleSet` - (Optional) Additional configuration for using the Account Takeover Protection managed rule group. Use this to specify information such as the sign-in page of your application and the type of content to accept or reject from the client. * `loginPath` - (Optional, **Deprecated**) The path of the login endpoint for your application. * `passwordField` - (Optional, **Deprecated**) Details about your login page password field. See [`passwordField`](#password_field-block) for more details. @@ -695,6 +696,14 @@ The `managedRuleGroupConfigs` block support the following arguments: * `inspectionLevel` - (Optional) The inspection level to use for the Bot Control rule group. +### `aws_managed_rules_acfp_rule_set` Block + +* `creation_path` - (Required) The path of the account creation endpoint for your application. This is the page on your website that accepts the completed registration form for a new user. This page must accept POST requests. +* `enable_regex_in_path` - (Optional) Whether or not to allow the use of regular expressions in the login page path. +* `registration_page_path` - (Required) The path of the account registration endpoint for your application. This is the page on your website that presents the registration form to new users. This page must accept GET text/html requests. +* `request_inspection` - (Optional) The criteria for inspecting login requests, used by the ATP rule group to validate credentials usage. See [`request_inspection`](#request_inspection-block) for more details. +* `response_inspection` - (Optional) The criteria for inspecting responses to login requests, used by the ATP rule group to track login failure rates. Note that Response Inspection is available only on web ACLs that protect CloudFront distributions. See [`response_inspection`](#response_inspection-block) for more details. + ### `awsManagedRulesAtpRuleSet` Block * `enableRegexInPath` - (Optional) Whether or not to allow the use of regular expressions in the login page path. diff --git a/website/docs/r/wafv2_web_acl.html.markdown b/website/docs/r/wafv2_web_acl.html.markdown index 6e21c1e2b3f..813e6f4b3fc 100644 --- a/website/docs/r/wafv2_web_acl.html.markdown +++ b/website/docs/r/wafv2_web_acl.html.markdown @@ -87,6 +87,78 @@ resource "aws_wafv2_web_acl" "example" { } ``` +### Account Creation Fraud Prevention + +```terraform +resource "aws_wafv2_web_acl" "acfp-example" { + name = "managed-acfp-example" + description = "Example of a managed ACFP rule." + scope = "CLOUDFRONT" + + default_action { + allow {} + } + + rule { + name = "acfp-rule-1" + priority = 1 + + override_action { + count {} + } + + statement { + managed_rule_group_statement { + name = "AWSManagedRulesACFPRuleSet" + vendor_name = "AWS" + + managed_rule_group_configs { + aws_managed_rules_acfp_rule_set { + creation_path = "/signin" + registration_page_path = "/register" + + request_inspection { + email_field { + identifier = "/email" + } + + password_field { + identifier = "/password" + } + + payload_type = "JSON" + + username_field { + identifier = "/username" + } + } + + response_inspection { + status_code { + failure_codes = ["403"] + success_codes = ["200"] + } + } + } + } + } + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "friendly-rule-metric-name" + sampled_requests_enabled = false + } + } + + visibility_config { + cloudwatch_metrics_enabled = false + metric_name = "friendly-metric-name" + sampled_requests_enabled = false + } +} +``` + ### Account Takeover Protection ```terraform @@ -667,6 +739,7 @@ The `rule_action_override` block supports the following arguments: The `managed_rule_group_configs` block support the following arguments: * `aws_managed_rules_bot_control_rule_set` - (Optional) Additional configuration for using the Bot Control managed rule group. Use this to specify the inspection level that you want to use. See [`aws_managed_rules_bot_control_rule_set`](#aws_managed_rules_bot_control_rule_set-block) for more details +* `aws_managed_rules_acfp_rule_set` - (Optional) Additional configuration for using the Account Creation Fraud Prevention managed rule group. Use this to specify information such as the registration page of your application and the type of content to accept or reject from the client. * `aws_managed_rules_atp_rule_set` - (Optional) Additional configuration for using the Account Takeover Protection managed rule group. Use this to specify information such as the sign-in page of your application and the type of content to accept or reject from the client. * `login_path` - (Optional, **Deprecated**) The path of the login endpoint for your application. * `password_field` - (Optional, **Deprecated**) Details about your login page password field. See [`password_field`](#password_field-block) for more details. @@ -677,6 +750,14 @@ The `managed_rule_group_configs` block support the following arguments: * `inspection_level` - (Optional) The inspection level to use for the Bot Control rule group. +### `aws_managed_rules_acfp_rule_set` Block + +* `creation_path` - (Required) The path of the account creation endpoint for your application. This is the page on your website that accepts the completed registration form for a new user. This page must accept POST requests. +* `enable_regex_in_path` - (Optional) Whether or not to allow the use of regular expressions in the login page path. +* `registration_page_path` - (Required) The path of the account registration endpoint for your application. This is the page on your website that presents the registration form to new users. This page must accept GET text/html requests. +* `request_inspection` - (Optional) The criteria for inspecting login requests, used by the ATP rule group to validate credentials usage. See [`request_inspection`](#request_inspection-block) for more details. +* `response_inspection` - (Optional) The criteria for inspecting responses to login requests, used by the ATP rule group to track login failure rates. Note that Response Inspection is available only on web ACLs that protect CloudFront distributions. See [`response_inspection`](#response_inspection-block) for more details. + ### `aws_managed_rules_atp_rule_set` Block * `enable_regex_in_path` - (Optional) Whether or not to allow the use of regular expressions in the login page path. From 2ad53fc84b322e9cf38631a76d51a602b80e76f5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 12 Oct 2023 14:56:39 -0400 Subject: [PATCH 2/3] Fix documentation terrafmt error. --- website/docs/r/wafv2_web_acl.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/wafv2_web_acl.html.markdown b/website/docs/r/wafv2_web_acl.html.markdown index 813e6f4b3fc..59489c7d8cc 100644 --- a/website/docs/r/wafv2_web_acl.html.markdown +++ b/website/docs/r/wafv2_web_acl.html.markdown @@ -121,7 +121,7 @@ resource "aws_wafv2_web_acl" "acfp-example" { email_field { identifier = "/email" } - + password_field { identifier = "/password" } From 66bfcca5f2e538f06a3149843e830c555ffe0f18 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 12 Oct 2023 15:02:18 -0400 Subject: [PATCH 3/3] Add CHANGELOG entry. --- .changelog/33915.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/33915.txt diff --git a/.changelog/33915.txt b/.changelog/33915.txt new file mode 100644 index 00000000000..29ad42ee95a --- /dev/null +++ b/.changelog/33915.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_wafv2_web_acl: Add `aws_managed_rules_acfp_rule_set` to `managed_rule_group_configs` configuration block +```