Skip to content

Commit

Permalink
feat(rules): add size constraint statement (#41)
Browse files Browse the repository at this point in the history
* feat(rules): add size constraint statement

Signed-off-by: Felipe Zipitria <[email protected]>

* feat(terratest): add tests to sizeconstraint statement

Signed-off-by: Felipe Zipitria <[email protected]>

* fix(ci): update go modules to fix terratest in GHA

Signed-off-by: Felipe Zipitria <[email protected]>
  • Loading branch information
fzipi360 authored Oct 20, 2021
1 parent fac013f commit b5672c1
Show file tree
Hide file tree
Showing 8 changed files with 1,062 additions and 189 deletions.
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Supported WAF v2 components:
- Byte Match statements
- Geo set statements
- Logical Statements (AND, OR, NOT)
- Size constraint statements

## Terraform versions

Expand Down Expand Up @@ -212,7 +213,32 @@ module "waf" {
type = "NONE"
}
}
}
},
### Size constraint Rule example
# Refer to https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl#size-constraint-statement
# for all of the options available.
# Additional examples available in the examples directory
{
name = "BodySizeConstraint"
priority = 0
size_constraint_statement = {
field_to_match = {
body = "{}"
}
comparison_operator = "GT"
size = 8192
priority = 0
type = "NONE"
}
action = "count"
visibility_config = {
cloudwatch_metrics_enabled = true
metric_name = "BodySizeConstraint"
sampled_requests_enabled = true
}
},
]
tags = {
Expand Down Expand Up @@ -281,7 +307,7 @@ Module managed by:

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | 3.50.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.50 |

## Modules

Expand Down
158 changes: 158 additions & 0 deletions examples/wafv2-sizeconstraint-rules/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
provider "aws" {
region = "eu-west-1"
}

#####
# Web Application Firewall configuration
#####
module "waf" {
source = "../.."

name_prefix = var.name_prefix

allow_default_action = true

scope = "REGIONAL"

create_alb_association = false

visibility_config = {
cloudwatch_metrics_enabled = false
metric_name = "${var.name_prefix}-waf-setup-waf-main-metrics"
sampled_requests_enabled = false
}

rules = [
{
name = "AWSManagedRulesCommonRuleSet-rule-1"
priority = "1"

override_action = "none"

visibility_config = {
cloudwatch_metrics_enabled = false
metric_name = "AWSManagedRulesCommonRuleSet-metric"
sampled_requests_enabled = false
}

managed_rule_group_statement = {
name = "AWSManagedRulesCommonRuleSet"
vendor_name = "AWS"
excluded_rule = [
"SizeRestrictions_QUERYSTRING",
"SizeRestrictions_BODY",
"GenericRFI_QUERYARGUMENTS"
]
}
},
{
name = "block-specific-uri-path"
priority = "2"
action = "block"

byte_match_statement = {
field_to_match = {
uri_path = "{}"
}
positional_constraint = "STARTS_WITH"
search_string = "/path/to/match"
priority = 0
type = "NONE" # The text transformation type
}

visibility_config = {
cloudwatch_metrics_enabled = false
sampled_requests_enabled = false
}
},
{
name = "block-if-request-body-contains-hotmail-email"
priority = "3"
action = "block"

byte_match_statement = {
field_to_match = {
body = "{}"
}
positional_constraint = "CONTAINS"
search_string = "@hotmail.com"
priority = 0
type = "NONE" # The text transformation type
}

visibility_config = {
cloudwatch_metrics_enabled = false
sampled_requests_enabled = false
}
},
{
name = "block-all-post-requests"
priority = "4"
action = "block"

byte_match_statement = {
field_to_match = {
method = "{}"
}
positional_constraint = "EXACTLY"
search_string = "post"
priority = 0
type = "LOWERCASE" # The text transformation type
}

visibility_config = {
cloudwatch_metrics_enabled = false
sampled_requests_enabled = false
}
},
{
# Blocks a single user by checking the username header
name = "block-single-user"
priority = "5"
action = "block"

byte_match_statement = {
field_to_match = {
single_header = {
name = "Username"
}
}
positional_constraint = "EXACTLY"
search_string = "testuser"
priority = 0
type = "LOWERCASE" # The text transformation type
}

visibility_config = {
cloudwatch_metrics_enabled = false
sampled_requests_enabled = false
}
},
{
name = "BodySizeConstraint"
priority = 0
size_constraint_statement = {
field_to_match = {
body = "{}"
}
comparison_operator = "GT"
size = 8192
priority = 0
type = "NONE"

}

action = "block"

visibility_config = {
cloudwatch_metrics_enabled = true
metric_name = "BodySizeConstraint"
sampled_requests_enabled = true
}
},
]

tags = {
"Environment" = "test"
}
}
24 changes: 24 additions & 0 deletions examples/wafv2-sizeconstraint-rules/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
output "web_acl_name" {
description = "The name of the WAFv2 WebACL."
value = module.waf.web_acl_name
}

output "web_acl_arn" {
description = "The ARN of the WAFv2 WebACL."
value = module.waf.web_acl_arn
}

output "web_acl_capacity" {
description = "The web ACL capacity units (WCUs) currently being used by this web ACL."
value = module.waf.web_acl_capacity
}

output "web_acl_visibility_config_name" {
description = "The web ACL visibility config name"
value = module.waf.web_acl_visibility_config_name
}

output "web_acl_rule_names" {
description = "List of created rule names"
value = module.waf.web_acl_rule_names
}
5 changes: 5 additions & 0 deletions examples/wafv2-sizeconstraint-rules/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
variable "name_prefix" {
description = "A prefix used for naming resources."
type = string
default = "example"
}
43 changes: 43 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,49 @@ resource "aws_wafv2_web_acl" "main" {
}
}

dynamic "size_constraint_statement" {
for_each = length(lookup(rule.value, "size_constraint_statement", {})) == 0 ? [] : [lookup(rule.value, "size_constraint_statement", {})]
content {
dynamic "field_to_match" {
for_each = length(lookup(size_constraint_statement.value, "field_to_match", {})) == 0 ? [] : [lookup(size_constraint_statement.value, "field_to_match", {})]
content {
dynamic "uri_path" {
for_each = length(lookup(field_to_match.value, "uri_path", {})) == 0 ? [] : [lookup(field_to_match.value, "uri_path")]
content {}
}
dynamic "all_query_arguments" {
for_each = length(lookup(field_to_match.value, "all_query_arguments", {})) == 0 ? [] : [lookup(field_to_match.value, "all_query_arguments")]
content {}
}
dynamic "body" {
for_each = length(lookup(field_to_match.value, "body", {})) == 0 ? [] : [lookup(field_to_match.value, "body")]
content {}
}
dynamic "method" {
for_each = length(lookup(field_to_match.value, "method", {})) == 0 ? [] : [lookup(field_to_match.value, "method")]
content {}
}
dynamic "query_string" {
for_each = length(lookup(field_to_match.value, "query_string", {})) == 0 ? [] : [lookup(field_to_match.value, "query_string")]
content {}
}
dynamic "single_header" {
for_each = length(lookup(field_to_match.value, "single_header", {})) == 0 ? [] : [lookup(field_to_match.value, "single_header")]
content {
name = lower(lookup(single_header.value, "name"))
}
}
}
}
comparison_operator = lookup(size_constraint_statement.value, "comparison_operator")
size = lookup(size_constraint_statement.value, "size")
text_transformation {
priority = lookup(size_constraint_statement.value, "priority")
type = lookup(size_constraint_statement.value, "type")
}
}
}

dynamic "rate_based_statement" {
for_each = length(lookup(rule.value, "rate_based_statement", {})) == 0 ? [] : [lookup(rule.value, "rate_based_statement", {})]
content {
Expand Down
15 changes: 1 addition & 14 deletions test/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,6 @@ module github.com/umotif-public/terraform-aws-waf-webaclv2/test
go 1.16

require (
github.com/agext/levenshtein v1.2.3 // indirect
github.com/gruntwork-io/gruntwork-cli v0.7.0 // indirect
github.com/gruntwork-io/terratest v0.35.1
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/hcl/v2 v2.10.0 // indirect
github.com/hashicorp/terraform-json v0.11.0 // indirect
github.com/jinzhu/copier v0.3.2 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/gruntwork-io/terratest v0.38.2
github.com/stretchr/testify v1.7.0
github.com/zclconf/go-cty v1.8.3 // indirect
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
Loading

0 comments on commit b5672c1

Please sign in to comment.