Skip to content

Commit dbcbdee

Browse files
committed
Enable header check for multiple headers
1 parent 970f97b commit dbcbdee

File tree

3 files changed

+105
-14
lines changed

3 files changed

+105
-14
lines changed

aws/waf/main.tf

+93-10
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,104 @@ resource "aws_wafv2_web_acl" "main" {
3131
block {}
3232
}
3333
}
34-
statement {
35-
byte_match_statement {
36-
field_to_match {
37-
single_header {
38-
name = lower(rule.value["header_name"])
34+
dynamic "statement" {
35+
for_each = length(rule.value["header_values"]) == 1 ? rule.value["header_values"] : {}
36+
content {
37+
dynamic "byte_match_statement" {
38+
for_each = length(statement.value["not_statement"]) == false ? [1] : []
39+
content {
40+
field_to_match {
41+
single_header {
42+
name = lower(statement.value["header_name"])
43+
}
44+
}
45+
46+
positional_constraint = "CONTAINS"
47+
48+
search_string = statement.value["header_value"]
49+
50+
text_transformation {
51+
priority = 1
52+
type = "LOWERCASE"
53+
}
54+
}
55+
}
56+
dynamic "not_statement" {
57+
for_each = length(statement.value["not_statement"]) == true ? [1] : []
58+
content {
59+
statement {
60+
byte_match_statement {
61+
field_to_match {
62+
single_header {
63+
name = lower(statement.value["header_name"])
64+
}
65+
}
66+
67+
positional_constraint = "CONTAINS"
68+
69+
search_string = statement.value["header_value"]
70+
71+
text_transformation {
72+
priority = 1
73+
type = "LOWERCASE"
74+
}
75+
}
76+
}
3977
}
4078
}
79+
}
80+
}
81+
dynamic "statement" {
82+
for_each = length(rule.value["header_values"]) > 1 ? rule.value["header_values"] : {}
83+
content {
84+
and_statement {
85+
dynamic "statement" {
86+
for_each = rule.value["header_values"]
87+
content {
88+
dynamic "byte_match_statement" {
89+
for_each = length(statement.value["not_statement"]) == false ? [1] : []
90+
content {
91+
field_to_match {
92+
single_header {
93+
name = lower(statement.value["header_name"])
94+
}
95+
}
4196

42-
positional_constraint = "CONTAINS"
97+
positional_constraint = "CONTAINS"
4398

44-
search_string = rule.value["header_value"]
99+
search_string = statement.value["header_value"]
45100

46-
text_transformation {
47-
priority = 1
48-
type = "LOWERCASE"
101+
text_transformation {
102+
priority = 1
103+
type = "LOWERCASE"
104+
}
105+
}
106+
}
107+
dynamic "not_statement" {
108+
for_each = length(statement.value["not_statement"]) == true ? [1] : []
109+
content {
110+
statement {
111+
byte_match_statement {
112+
field_to_match {
113+
single_header {
114+
name = lower(statement.value["header_name"])
115+
}
116+
}
117+
118+
positional_constraint = "CONTAINS"
119+
120+
search_string = statement.value["header_value"]
121+
122+
text_transformation {
123+
priority = 1
124+
type = "LOWERCASE"
125+
}
126+
}
127+
}
128+
}
129+
}
130+
}
131+
}
49132
}
50133
}
51134
}

aws/waf/outputs.tf

+5
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,8 @@ output "aws_waf_arn" {
22
description = "The arn for AWS WAF WebACL."
33
value = aws_wafv2_web_acl.main.arn
44
}
5+
6+
output "waf_logs_sns_topic_arn" {
7+
description = "The arn for the SNS topic to receive the AWS WAF logs"
8+
value = aws_sns_topic.waf_logs_sns_subscription.arn
9+
}

aws/waf/variables.tf

+7-4
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@ variable "rate_limit_rules" {
4646
variable "header_match_rules" {
4747
description = "Rule statement to inspect and match the header for an incoming request."
4848
type = map(object({
49-
name = string # Name of the header match rule group
50-
priority = number # Relative processing order for header match rule relative to other rules processed by AWS WAF.
51-
header_name = string # This is the name of the header to inspect for all incoming requests.
52-
header_value = string # This is the value to look out for a matching header name for all incoming requests
49+
name = string # Name of the header match rule group
50+
priority = number # Relative processing order for header match rule relative to other rules processed by AWS WAF.
51+
header_values = map(object({ # Header values contains a map of headers to inspect. You can provide multiple headers and values, all headers will be inspected together with `AND` logic.
52+
header_name = string # This is the name of the header to inspect for all incoming requests.
53+
header_value = string # This is the value to look out for a matching header name for all incoming requests
54+
not_statement = optional(bool, false) # This indicates if the result this header match should be negated. The negated result will be joined with other header match results using `AND` logic if more than 1 header is provided.
55+
}))
5356
count_override = optional(bool, true) # If true, this will override the rule action setting to `count`, if false, the rule action will be set to `block`. Default value is false.
5457
}))
5558

0 commit comments

Comments
 (0)