10
1

More than 1 year has passed since last update.

AWSのWAFでブロックされた正規アクセスを許可する

Last updated at Posted at 2022-12-19

概要

開発中のwebサービスにコメント投稿機能があるのですが、コメント内にURLを含むとコメントが出来ないことが分かりました。
調べてみるとAWSのWAFでブロックされていることが分かったので、許可ルールとして登録することでコメントできるように対応しました。

環境

AWSでECSを使ってアプリをデプロイしており、ELBで外部からのアクセスを受けています。
ELBにWAFをアタッチしており、不正アクセスをブロックしているという環境です。
image.png

発生事象

コメント内にURLを含むとコメントすると403エラーとなっており、ELBののログを見るとWAFにブロックされていました。
さらにWAFのサンプルリクエスト機能からコメント投稿に関するアクセスを検索してみると、WAFに設定したブロックのルールに該当していました。

対象のルールは Fortinet Managed Rules for AWS WAF - Complete OWASP Top 10を適用したもので、URL付きのコメントをクロスサイトスクリプティングとみなしてブロックしていました。

アプリ側で改修する方法もありますが、一旦WAFで許可することにします。

対応内容

WAFはterraformで管理しているので、terraformで aws_wafv2_regex_pattern_setaws_wafv2_rule_groupリソースを新たに作成し、aws_wafv2_web_aclの中に許可ルールを追加することでコメント投稿のURLからのみ投稿できるようにしました。

  • aws_wafv2_regex_pattern_set
    コメント用のURLを正規表現で登録します。
resource "aws_wafv2_regex_pattern_set" "this" {
  name = aws_wafv2_regex_pattern_set
  scope = "REGIONAL"

  regular_expression {
    regex_string = "foo/bar/ID[A-Z0-9]*/comments" ## コメントのURLを正規表現で登録
  }
}

  • aws_wafv2_rule_group
    aws_wafv2_regex_pattern_setのURLかつHTTPのメソッドが(POST|PUT|PATCH)のものを許可するルールグループを作成します。
resource "aws_wafv2_rule_group" "this" {
  name     = aws_wafv2_rule_group
  scope    = "REGIONAL"
  capacity = 50

  rule {
    name     = "allow_requests"
    priority = 4

    action {
      allow {}
    }

    statement {
      and_statement {
        statement {
          regex_pattern_set_reference_statement {
            arn = aws_wafv2_regex_pattern_set.this.arn

            field_to_match {
              uri_path {}
            }

            text_transformation {
              priority = 0
              type     = "NONE"
            }
          }
        }
        statement {
          or_statement {
            statement {
              byte_match_statement {
                field_to_match {
                  method {}   
                }
                search_string = "POST"
                positional_constraint = "EXACTLY"

                text_transformation {
                  priority = 0
                  type     = "NONE"
                }
              }
            }
            statement {
              byte_match_statement {
                field_to_match {
                  method {}   
                }
                search_string = "PUT"
                positional_constraint = "EXACTLY"

                text_transformation {
                  priority = 0
                  type     = "NONE"
                }
              }
            }
            statement {
              byte_match_statement {
                field_to_match {
                  method {}   
                }
                search_string = "PATCH"
                positional_constraint = "EXACTLY"

                text_transformation {
                  priority = 0
                  type     = "NONE"
                }
              }
            }
          }
        }
      }
    }
    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "allow_requests"
      sampled_requests_enabled   = true
    }
  }
  visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "allow_requests"
      sampled_requests_enabled   = true
  }
}

  • aws_wafv2_web_acl
    Fortinetのルールでブロックされていたので、Fortinetの手前のpriorityとしてルールを追加します。
resource "aws_wafv2_web_acl" "this" {
  name  = aws_wafv2_web_acl
  scope = "REGIONAL"

  default_action {
    allow {}
  }

  rule {
    name     = "AWS-managed_rules_amazon_ip_reputation_list"
    priority = 1

    override_action {
      none {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesAmazonIpReputationList"
        vendor_name = "AWS"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "AWS-managed_rules_amazon_ip_reputation_list"
      sampled_requests_enabled   = true
    }
  }

    # 追加ルール
  rule {
    name     = "allow_requests"
    priority = 2

    override_action {
      none {}
    }

    statement {
      rule_group_reference_statement {
        arn = aws_wafv2_rule_group.this.arn
      }
    }
    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "allow_requests"
      sampled_requests_enabled   = true
    }
  }

  rule {
    name     = "Fortinet-all_rules"
    priority = 3
    override_action {
      none {}
    }

    statement {
      managed_rule_group_statement {
        name        = "all_rules"
        vendor_name = "Fortinet"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "Fortinet-all_rules"
      sampled_requests_enabled   = true
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name                = "WebACL"
    sampled_requests_enabled   = true
  }
}

対応結果

コメントを投稿してみます。

WAFのサンプルリクエスト機能から追加したルールでフィルタすると、コメント投稿のアクションがALLOWとなっていることが確認できました。
image.png

参考

10
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
1