diff --git a/internal/services/network/web_application_firewall_policy_resource.go b/internal/services/network/web_application_firewall_policy_resource.go index 12053a12fd61..a93f5df64312 100644 --- a/internal/services/network/web_application_firewall_policy_resource.go +++ b/internal/services/network/web_application_firewall_policy_resource.go @@ -396,6 +396,22 @@ func resourceWebApplicationFirewallPolicy() *pluginsdk.Resource { Default: true, }, + "file_upload_enforcement": { + Type: pluginsdk.TypeBool, + /* + NOTE: O+C: This value defaults to true but is only available under certain conditions (i.e. when version is 3.2) + managed_rules { + managed_rule_set { + type = "OWASP" + version = "3.2" + } + } + */ + Optional: true, + // We'll remove computed in 5.0 so we don't break existing configurations + Computed: !features.FivePointOhBeta(), + }, + "max_request_body_size_in_kb": { Type: pluginsdk.TypeInt, Optional: true, @@ -727,12 +743,14 @@ func expandWebApplicationFirewallPolicyPolicySettings(input []interface{}) *weba mode := v["mode"].(string) requestBodyCheck := v["request_body_check"].(bool) requestBodyEnforcement := v["request_body_enforcement"].(bool) + fileUploadEnforcement := v["file_upload_enforcement"].(bool) maxRequestBodySizeInKb := v["max_request_body_size_in_kb"].(int) fileUploadLimitInMb := v["file_upload_limit_in_mb"].(int) result := webapplicationfirewallpolicies.PolicySettings{ State: pointer.To(enabled), Mode: pointer.To(webapplicationfirewallpolicies.WebApplicationFirewallMode(mode)), + FileUploadEnforcement: pointer.To(fileUploadEnforcement), RequestBodyCheck: pointer.To(requestBodyCheck), RequestBodyEnforcement: pointer.To(requestBodyEnforcement), MaxRequestBodySizeInKb: pointer.To(int64(maxRequestBodySizeInKb)), @@ -1088,6 +1106,7 @@ func flattenWebApplicationFirewallPolicyPolicySettings(input *webapplicationfire result["mode"] = string(pointer.From(input.Mode)) result["request_body_check"] = input.RequestBodyCheck result["request_body_enforcement"] = input.RequestBodyEnforcement + result["file_upload_enforcement"] = input.FileUploadEnforcement result["max_request_body_size_in_kb"] = int(pointer.From(input.MaxRequestBodySizeInKb)) result["file_upload_limit_in_mb"] = int(pointer.From(input.FileUploadLimitInMb)) result["log_scrubbing"] = flattenWebApplicationFirewallPolicyLogScrubbing(input.LogScrubbing) diff --git a/internal/services/network/web_application_firewall_policy_resource_test.go b/internal/services/network/web_application_firewall_policy_resource_test.go index f27211b69546..6477b998a95a 100644 --- a/internal/services/network/web_application_firewall_policy_resource_test.go +++ b/internal/services/network/web_application_firewall_policy_resource_test.go @@ -405,6 +405,35 @@ func TestAccWebApplicationFirewallPolicy_BotManager(t *testing.T) { }) } +func TestAccWebApplicationFirewallPolicy_fileUploadEnforcement(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_web_application_firewall_policy", "test") + r := WebApplicationFirewallResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.fileUploadEnforcement(data, true), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.fileUploadEnforcement(data, false), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.fileUploadEnforcement(data, true), + 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 := webapplicationfirewallpolicies.ParseApplicationGatewayWebApplicationFirewallPolicyID(state.ID) if err != nil { @@ -2035,3 +2064,40 @@ resource "azurerm_web_application_firewall_policy" "test" { } `, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } + +func (WebApplicationFirewallResource) fileUploadEnforcement(data acceptance.TestData, enforcement bool) 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 + + + managed_rules { + managed_rule_set { + type = "OWASP" + version = "3.2" + } + } + + policy_settings { + enabled = true + mode = "Prevention" + request_body_check = false + request_body_enforcement = true + file_upload_limit_in_mb = 128 + max_request_body_size_in_kb = 128 + file_upload_enforcement = %t + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, enforcement) +} diff --git a/website/docs/r/web_application_firewall_policy.html.markdown b/website/docs/r/web_application_firewall_policy.html.markdown index ffad314bf859..16500d00d16c 100644 --- a/website/docs/r/web_application_firewall_policy.html.markdown +++ b/website/docs/r/web_application_firewall_policy.html.markdown @@ -196,6 +196,8 @@ The `policy_settings` block supports the following: * `js_challenge_cookie_expiration_in_minutes` - (Optional) Specifies the JavaScript challenge cookie validity lifetime in minutes. The user is challenged after the lifetime expires. Accepted values are in the range `5` to `1440`. Defaults to `30`. +* `file_upload_enforcement` - (Optional) - Whether the firewall should block a request with upload size greater then `file_upload_limit_in_mb`. + --- The `managed_rules` block supports the following: