diff --git a/ci/terraform/.terraform.lock.hcl b/ci/terraform/.terraform.lock.hcl index 205f4390c..f7812d324 100644 --- a/ci/terraform/.terraform.lock.hcl +++ b/ci/terraform/.terraform.lock.hcl @@ -2,29 +2,29 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/aws" { - version = "5.34.0" - constraints = "5.34.0" + version = "5.45.0" + constraints = "5.45.0" hashes = [ - "h1:1UEoNI8LGCKvrl0+60qYm0wY8uOoKmF0W+HnuAI1U4k=", - "h1:1Y1JgV1z99QqAK06+atyfNqreZxyGZKbm4mZO4VhhT8=", - "h1:CUCoX4ax5hrP6BH4973oP+hgz8VR2GuNPQil3FYwEqQ=", - "h1:Tbq6dKE+XyXmkup6+7eQj2vH+eCJipk8R3VXhebVYi4=", - "h1:YSSLSKX6xN6NM2SeqKKpzvQyp6XVx9z1n3CVXwDLznQ=", - "zh:01bb20ae12b8c66f0cacec4f417a5d6741f018009f3a66077008e67cce127aa4", - "zh:3b0c9bdbbf846beef2c9573fc27898ceb71b69cf9d2f4b1dd2d0c2b539eab114", - "zh:5226ecb9c21c2f6fbf1d662ac82459ffcd4ad058a9ea9c6200750a21a80ca009", - "zh:6021b905d9b3cd3d7892eb04d405c6fa20112718de1d6ef7b9f1db0b0c97721a", + "h1:4Vgk51R7iTY1oczaTQDG+DkA9nE8TmjlUtecqXX6qDU=", + "h1:8m3+C1VNevzU/8FsABoKp2rTOx3Ue7674INfhfk0TZY=", + "h1:RSt0f6GHUbH1OCtF5r6BWRxuZxaFopsAcpuEAmOc2MY=", + "h1:ihJwo9TmCngWRqLb/+kBeLuvAWMjLu/WV0zGSvypBv4=", + "h1:xFKE0MsBjV86pMpbrLbAHCzv5kREDYO0xt5LRZMeZn8=", + "zh:1379bcf45aef3d486ee18b4f767bfecd40a0056510d26107f388be3d7994c368", + "zh:1615a6f5495acfb3a0cb72324587261dd4d72711a3cc51aff13167b14531501e", + "zh:18b69a0f33f8b1862fbd3f200756b7e83e087b73687085f2cf9c7da4c318e3e6", + "zh:2c5e7aecd197bc3d3b19290bad8cf4c390c2c6a77bb165da4e11f53f2dfe2e54", + "zh:3794da9bef97596e3bc60e12cdd915bda5ec2ed62cd1cd93723d58b4981905fe", + "zh:40a5e45ed91801f83db76dffd467dcf425ea2ca8642327cf01119601cb86021c", + "zh:4abfc3f53d0256a7d5d1fa5e931e4601b02db3d1da28f452341d3823d0518f1a", + "zh:4eb0e98078f79aeb06b5ff6115286dc2135d12a80287885698d04036425494a2", + "zh:75470efbadea4a8d783642497acaeec5077fc4a7f3df3340defeaa1c7de29bf7", + "zh:8861a0b4891d5fa2fa7142f236ae613cea966c45b5472e3915a4ac3abcbaf487", + "zh:8bf6f21cd9390b742ca0b4393fde92616ca9e6553fb75003a0999006ad233d35", "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:9e61b8e0ccf923979cd2dc1f1140dbcb02f92248578e10c1996f560b6306317c", - "zh:ad6bf62cdcf531f2f92f6416822918b7ba2af298e4a0065c6baf44991fda982d", - "zh:b698b041ef38837753bbe5265dddbc70b76e8b8b34c5c10876e6aab0eb5eaf63", - "zh:bb799843c534f6a3f072a99d93a3b53ff97c58a96742be15518adf8127706784", - "zh:cebee0d942c37cd3b21e9050457cceb26d0a6ea886b855dab64bb67d78f863d1", - "zh:e061fdd1cb99e7c81fb4485b41ae000c6792d38f73f9f50aed0d3d5c2ce6dcfb", - "zh:eeb4943f82734946362696928336357cd1d36164907ae5905da0316a67e275e1", - "zh:ef09b6ad475efa9300327a30cbbe4373d817261c8e41e5b7391750b16ef4547d", - "zh:f01aab3881cd90b3f56da7c2a75f83da37fd03cc615fc5600a44056a7e0f9af7", - "zh:fcd0f724ebc4b56a499eb6c0fc602de609af18a0d578befa2f7a8df155c55550", + "zh:ad73008a044e75d337acda910fb54d8b81a366873c8a413fec1291034899a814", + "zh:bf261713b0b8bebfe8c199291365b87d9043849f28a2dc764bafdde73ae43693", + "zh:da3bafa1fd830be418dfcc730e85085fe67c0d415c066716f2ac350a2306f40a", ] } diff --git a/ci/terraform/site.tf b/ci/terraform/site.tf index 9645f977a..208993deb 100644 --- a/ci/terraform/site.tf +++ b/ci/terraform/site.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = "= 5.34.0" + version = "= 5.45.0" } random = { source = "hashicorp/random" diff --git a/ci/terraform/variables.tf b/ci/terraform/variables.tf index f93b6cb52..f8400bacf 100644 --- a/ci/terraform/variables.tf +++ b/ci/terraform/variables.tf @@ -261,3 +261,21 @@ variable "alb_idle_timeout" { description = "Frontend Application Load Balancer idle timeout" default = 60 } + +variable "rate_limited_endpoints" { + description = "List of endpoints that should be rate limited by session and IP" + type = list(string) + default = [] +} + +variable "rate_limited_endpoints_rate_limit_period" { + description = "Period in seconds for rate limiting for rate limited endpoints" + type = number + default = 120 +} + +variable "rate_limited_endpoints_requests_per_period" { + description = "Number of requests per period allowed for rate limited endpoints" + type = number + default = 100000 +} diff --git a/ci/terraform/waf.tf b/ci/terraform/waf.tf index c50ed7c8e..f86ab279d 100644 --- a/ci/terraform/waf.tf +++ b/ci/terraform/waf.tf @@ -91,6 +91,109 @@ resource "aws_wafv2_web_acl" "frontend_alb_waf_regional_web_acl" { } } + rule { + name = "BlockMoreThan100CheckYourEmailRequestsFromIPPer5Minutes" + priority = 21 + rule_label { + name = "MoreThan100CheckYourEmailRequestsFromIPPer5Minutes" + } + + action { + block {} + } + + statement { + rate_based_statement { + limit = var.environment == "staging" ? 20000000 : var.rate_limited_endpoints_requests_per_period + evaluation_window_sec = var.rate_limited_endpoints_rate_limit_period + aggregate_key_type = "IP" + + + scope_down_statement { + or_statement { + dynamic "statement" { + for_each = var.rate_limited_endpoints + content { + byte_match_statement { + positional_constraint = "STARTS_WITH" + search_string = statement.value + field_to_match { + uri_path {} + } + text_transformation { + priority = 0 + type = "LOWERCASE" + } + } + } + } + } + } + } + } + + visibility_config { + cloudwatch_metrics_enabled = true + metric_name = "${replace(var.environment, "-", "")}FrontendAlbWafMoreThan100CheckYourEmailRequestsFromIPPer5Minutes" + sampled_requests_enabled = true + } + } + + rule { + name = "BlockMoreThan100CheckYourEmailRequestsFromApsSessionPer5Minutes" + priority = 22 + + rule_label { + name = "MoreThan100CheckYourEmailRequestsFromApsSessionPer5Minutes" + } + + action { + block {} + } + + statement { + rate_based_statement { + limit = var.environment == "staging" ? 20000000 : var.rate_limited_endpoints_requests_per_period + evaluation_window_sec = var.rate_limited_endpoints_rate_limit_period + aggregate_key_type = "CUSTOM_KEYS" + custom_key { + cookie { + name = "aps" + text_transformation { + priority = 0 + type = "URL_DECODE" + } + } + } + scope_down_statement { + or_statement { + dynamic "statement" { + for_each = var.rate_limited_endpoints + content { + byte_match_statement { + positional_constraint = "STARTS_WITH" + search_string = statement.value + field_to_match { + uri_path {} + } + text_transformation { + priority = 0 + type = "LOWERCASE" + } + } + } + } + } + } + } + } + visibility_config { + cloudwatch_metrics_enabled = true + metric_name = "${replace(var.environment, "-", "")}FrontendAlbWafMoreThan100CheckYourEmailRequestsFromApsSessionPer5Minutes" + sampled_requests_enabled = true + } + } + rule { override_action { none {} @@ -275,7 +378,6 @@ resource "aws_wafv2_web_acl" "frontend_alb_waf_regional_web_acl" { } } } - visibility_config { cloudwatch_metrics_enabled = true metric_name = "${replace(var.environment, "-", "")}FrontendAlbWafContactUsCount"