Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Seperate WAF uri checks contexts between API and App #896

Merged
merged 10 commits into from
Nov 21, 2024
131 changes: 112 additions & 19 deletions aws/load_balancer/waf.tf
Original file line number Diff line number Diff line change
Expand Up @@ -299,31 +299,115 @@ resource "aws_wafv2_web_acl" "forms_acl" {
statement {
not_statement {
statement {
regex_pattern_set_reference_statement {
arn = aws_wafv2_regex_pattern_set.valid_app_uri_paths.arn
field_to_match {
uri_path {}
}
text_transformation {
priority = 1
type = "COMPRESS_WHITE_SPACE"
and_statement {
statement {
or_statement {
dynamic "statement" {
for_each = var.domains
content {
byte_match_statement {
positional_constraint = "EXACTLY"
field_to_match {
single_header {
name = "host"
}
}
search_string = statement.value
text_transformation {
priority = 1
type = "LOWERCASE"
}
}
}
}
}

}
text_transformation {
priority = 2
type = "LOWERCASE"
statement {
regex_pattern_set_reference_statement {
arn = aws_wafv2_regex_pattern_set.valid_app_uri_paths.arn
field_to_match {
uri_path {}
}
text_transformation {
priority = 1
type = "COMPRESS_WHITE_SPACE"
}
text_transformation {
priority = 2
type = "LOWERCASE"
}
}
}
}
}
}
}


visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AllowOnlyAppUrls"
sampled_requests_enabled = false
}
}

rule {
name = "AllowOnlyApiUrls"
priority = 65

action {
block {}
}

statement {
not_statement {
statement {
and_statement {
statement {
byte_match_statement {
positional_constraint = "EXACTLY"
field_to_match {
single_header {
name = "host"
}
}
search_string = var.domain_api
text_transformation {
priority = 1
type = "LOWERCASE"
}
}
}
statement {
regex_pattern_set_reference_statement {
arn = aws_wafv2_regex_pattern_set.valid_app_uri_paths.arn
bryan-robitaille marked this conversation as resolved.
Show resolved Hide resolved
field_to_match {
uri_path {}
}
text_transformation {
priority = 1
type = "COMPRESS_WHITE_SPACE"
}
text_transformation {
priority = 2
type = "LOWERCASE"
}
}
}
}
}
}
}


visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AllowOnlyApiUrls"
sampled_requests_enabled = false
}
}

rule {
name = local.cognito_login_outside_canada_rule_name
priority = 70
Expand Down Expand Up @@ -433,35 +517,44 @@ resource "aws_wafv2_web_acl_logging_configuration" "firehose_waf_logs_forms" {
resource "aws_wafv2_regex_pattern_set" "valid_app_uri_paths" {
name = "valid_app_uri_paths"
scope = "REGIONAL"
description = "Regex to match the app and api valid urls"
description = "Regex to match the app valid urls"

# App paths
regular_expression {
regex_string = "^\\/(?:en|fr)?\\/?(?:(admin|id|api|auth|signup|profile|forms|unsupported-browser|terms-of-use|contact|support|404)(?:\\/[\\w-]+)?)(?:\\/.*)?$"
regex_string = "^\\/(?:en|fr)?\\/?(?:(admin|form-builder|forms|id|auth|profile|support|contact|unlock-publishing)(?:\\/[\\w-]+)?)(?:\\/.*)?$"
}

# Static Pages
regular_expression {
regex_string = "^\\/(?:en|fr)?\\/?(?:(form-builder|sla|unlock-publishing|terms-and-conditions|javascript-disabled)(?:\\/[\\w-]+)?)(?:\\/.*)?$"
regex_string = "^\\/(?:en|fr)?\\/?(?:(sla|terms-and-conditions|terms-of-use|unsupported-browser|javascript-disabled|404)(?:\\/[\\w-]+)?)(?:\\/.*)?$"
}

# Files
regular_expression {
regex_string = "^\\/(?:en|fr)?\\/?(?:(static|_next|img|favicon\\.ico)(?:\\/[\\w-]+)*)(?:\\/.*)?$"
}

# API paths
regular_expression {
regex_string = "^\\/(?:v1)?\\/?(?:(docs|status))(?:\\/)?$"
}

# This is a temporary rule to allow search engines tools to access ownership verification files
regular_expression {
regex_string = "^\\/?(BingSiteAuth\\.xml|googlef34bd8c094c26cb0\\.html)$"
}

# Language selector page
regular_expression {
regex_string = "^\\/(?:en|fr)?\\/?$"
}
}

resource "aws_wafv2_regex_pattern_set" "valid_api_uri_paths" {
name = "valid_api_uri"
scope = "REGIONAL"
description = "Regex to match the api valid urls"

regular_expression {
regex_string = "^(?:\\/v1)?\\forms\\/(?:(c[a-z0-9]{24}))\\/(?:(template|(?:(submission\\/(?:(new|(?:([0-9]{2}-[0-9]{2}-[a-z0-9]{4})\\/?(?:(confirm|problem)?))))))))(?:\\/)?$"
}
bryan-robitaille marked this conversation as resolved.
Show resolved Hide resolved
}

resource "aws_wafv2_regex_pattern_set" "forms_base_url" {
name = "forms_base_url"
description = "Regex matching the root domain of GCForms"
Expand Down