Allow POST legitimate requests with base64 encoded data bypass AWS WAF

50 Views Asked by At

I'm trying to let WAF allow legitimate POST requests in JSON with two properties:

  • uuid, string
  • image, string which is a base64 representation

From ALB logs I noticed the requests were dumped by WAF. If I'd disable the ACL, requests would go through.

I had the following managed rules:

  • AWSManagedRulesCommonRuleSet
  • AWSManagedRulesAmazonIpReputationList
  • AWSManagedRulesKnownBadInputsRuleSet

I tried creating a new rule and attach it to a regex pattern set but I wasn't able to make it work as expected.

I've tried to set the keys and the value pattern, thinking that having the rule allow would help me get requests passed through and skip the rest of rules.

This is my rule, defined in Terraform:

resource "aws_wafv2_regex_pattern_set" "json_pattern_set" {
  name                  = "jsonPatternSet"
  scope                 = "REGIONAL"
  regular_expression {
    regex_string = "\"uuid\": \"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\""
  }
  regular_expression {
    regex_string = "\"image\": \"data:image/png;base64,.*\""
  }
}

And this is the defined rule, which I set with the smallest priority in the understanding of the execution order.

  rule {
    name     = "allow-social-share"
    priority = 0
    action {
      allow {}
    }

    statement {
      regex_pattern_set_reference_statement {
        arn = aws_wafv2_regex_pattern_set.json_pattern_set.arn
        field_to_match {
          body {}
        }
        text_transformation {
          priority = 0
          type     = "NONE"
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "${var.resources_name_prefix}-allow-social-share"
      sampled_requests_enabled   = true
    }
  }

Finally this is my complete ACL terraform definition:

resource "aws_wafv2_web_acl" "acl" {
  name        = "${var.resources_name_prefix}-waf-acl"
  scope       = "REGIONAL"

  default_action {
    allow {}
  }

  rule {
    name     = "allow-social-share"
    priority = 0
    action {
      allow {}
    }

    statement {
      regex_pattern_set_reference_statement {
        arn = aws_wafv2_regex_pattern_set.json_pattern_set.arn
        field_to_match {
          body {}
        }
        text_transformation {
          priority = 0
          type     = "NONE"
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "${var.resources_name_prefix}-allow-social-share"
      sampled_requests_enabled   = true
    }
  }

  rule {
    name     = "managed-common-rules"
    priority = 1
    override_action {
      none {}
    }
    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesCommonRuleSet"
        vendor_name = "AWS"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "${var.resources_name_prefix}-managed-common-rules"
      sampled_requests_enabled   = true
    }
  }

  rule {
    name     = "ip-reputation-rules"
    priority = 2
    override_action {
      none {}
    }
    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesAmazonIpReputationList"
        vendor_name = "AWS"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "${var.resources_name_prefix}-ip-reputation-rules"
      sampled_requests_enabled   = true
    }
  }

  rule {
    name     = "known-bad-inputs"
    priority = 3
    override_action {
      none {}
    }
    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesKnownBadInputsRuleSet"
        vendor_name = "AWS"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "${var.resources_name_prefix}-known-bad-inputs"
      sampled_requests_enabled   = true
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "${var.resources_name_prefix}-waf"
    sampled_requests_enabled   = false
  }
}

resource "aws_wafv2_regex_pattern_set" "json_pattern_set" {
  name                  = "jsonPatternSet"
  scope                 = "REGIONAL"
  regular_expression {
    regex_string = "\"uuid\": \"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\""
  }
  regular_expression {
    regex_string = "\"image\": \"data:image/png;base64,.*\""
  }
}

resource "aws_wafv2_web_acl_association" "association" {
  resource_arn = var.alb_arn
  web_acl_arn   = aws_wafv2_web_acl.acl.arn
}
0

There are 0 best solutions below