AWS Security Hub の検出結果を自動で「通知済み」にする

AWS Security Hub の検出結果を自動で「通知済み」にする

Clock Icon2022.09.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

Security Hub 検知の通知(or 自動起票)の悩み

AWS Security Hub にセキュリティイベントを集約して、 アクションのトリガーを作成するケースは多いです。 「メール・Slackへ通知」するケースもありますし、 「特定タスク管理ツールへ自動起票する」仕組みを作ることもあります。 例えば以下のブログでは、「Security Hub検知をBacklogへ自動起票する仕組み」を作っています。

こういった通知(or 自動起票)の仕組みを作ったときに出てくる悩みとして、 「定期的に同じ通知が飛んでくる」があります。 これはSecurity Hubの定期的なチェックのためです。 チェックを行うたびに検出結果が更新されて、それが検知されます。

最初のチェックの後、各コントロールのスケジュールは、定期的に実行されるか、変更によってトリガーされます。

  • 定期的なチェックは、最後の実行から 12 時間以内に自動的に実行 されます。周期を変更することはできません。
  • 変更によってトリガーされるチェックは、関連付けられたリソースの状態が変更されたときに実行されます。リソースの状態が変わらない場合でも、変更によってトリガーされるチェックの更新時刻は 18 時間ごとに更新 されます。これは、コントロールがまだ有効であることを知るのに便利です。

– 引用: セキュリティチェックの実行スケジュール - AWS Security Hub

ワークフローステータスの活用

同じ通知が飛ばないようにするためには ワークフローのステータス を活用できます。 これは各検出結果に設定できるステータスです。 NEW (新規), NOTIFIED (通知済み) SUPPRESSED (抑制済み), RESOLVED (解決済み) の4値のいずれかを設定できます。

img

例えば通知された検出結果を NOTIFIED (通知済み)に変更したとします。 EventBridgeルールで「 NOTIFIED にしたものは通知対象外にする」フィルタ(参考: 例3)を設定することで、 その通知( NOTIFIED にしたもの ) は再度通知されなくなります。

『「通知済み」にする』を自動化する

今回は「通知された検出結果を NOTIFIED (通知済み)に変更する」部分を 自動化します。Step Functionsを使って簡単に実装できます。

作ったもの

以下リソース(EventBridge, Step Functions)を作りました。

img

EventBridgeルール(フィルタ)

EventBridgeルールのフィルタパターンは以下のようにしました。 CRITICALの検出結果で失敗しているコントロールを検知します。

{
  "detail": {
    "findings": {
      "Compliance": {
        "Status": [{
          "anything-but": "PASSED"
        }]
      },
      "ProductName": ["Security Hub"],
      "RecordState": ["ACTIVE"],
      "Severity": {
        "Label": ["CRITICAL"]
      },
      "Workflow": {
        "Status": ["NEW"]
      }
    }
  },
  "detail-type": ["Security Hub Findings - Imported"],
  "source": ["aws.securityhub"]
}

【注意】ワークフローのステータス(Workflow.Status)のフィルタを必ず付与してください。 このフィルタがないと以下のようなループが発生します。

  1. 検出結果がEventBridge で検知、Step Functionsステートマシンが起動される
  2. 検出結果を「通知済み」に更新する
  3. 更新した検出結果が EventBridge で検知、Step Functionsステートマシンが起動される
  4. 検出結果を「通知済み」に更新する
  5. 更新した検出結果が EventBridge で検知、Step Functionsステートマシンが起動される
  6. 検出結果を「通知済み」に更新する
  7. (以下無限ループ)

EventBridgeルール(ターゲット)

EventBridgeルールのターゲット設定は以下のとおり。Step Functionsステートマシンを指定します。

img

ターゲットにステートマシンを指定するときに、IAMロールが必要になります。 キャプチャの test-security-events-role の部分です。 IAMロールのポリシーは以下のように 「ステートマシンの起動」のみを許可しています。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "states:StartExecution",
      "Resource": "${aws_sfn_state_machine.this.arn}"
    }
  ]
}

Step Functionsステートマシン

ステートマシンの構成は以下のとおり。見てのとおりシンプルです。

img

BatchUpdateFindings APIを実行しています。 入力パラメータは以下のとおり。

{
  "FindingIdentifiers": [
    {
      "Id.$": "$.detail.findings[0].Id",
      "ProductArn.$": "$.detail.findings[0].ProductArn"
    }
  ],
  "Workflow": {
    "Status": "NOTIFIED"
  }
}

(追記) ステートマシンのIAMロールには以下のように、 securityhub:BatchUpdateFindings アクションを許可する必要があります。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "securityhub:BatchUpdateFindings"
      ],
      "Resource": "*"
    }
  ]
}

確認

「SSHを全開放」なEC2セキュリティグループを作成してみます。 これは基礎セキュリティのベストプラクティスの [EC2.19] Security groups should not allow unrestricted access to ports with high risk にて非準拠になります。

img

しばらくして確認すると、すでに NOTIFIED になっていました。

img

ステートマシンの実行ログも確認しました。問題ないですね。

img

おわりに

AWS Security Hub の検出結果を自動で「通知済み」にする仕組みを作ってみました。

実際にはこれ単体で使うことは無いです。 以下のような組み合わせで活用する想定です。

  • このステートマシンに「通知(or 自動起票)の処理」を追加する
  • EventBridgeルールのターゲットに「通知(or 自動起票)の処理」を追加する 等

以上、参考になれば幸いです。

参考

追記情報

【2023-09-15】 ループがそもそも出ないように対策した Step Functions ステートマシン

【注意】ワークフローのステータス(Workflow.Status)のフィルタを必ず付与してください。 このフィルタがないと以下のようなループが発生します。

上記のループ対策版 Step Functions ステートマシンを以下に記載します。

{
  "Comment": "Security Hub finding handler",
  "StartAt": "Choice by workflow status",
  "States": {
    "Choice by workflow status": {
      "Type": "Choice",
      "Choices": [
        {
          "Not": {
            "Variable": "$.detail.findings[0].Workflow.Status",
            "StringEquals": "NOTIFIED"
          },
          "Comment": "not NOTIFIED",
          "Next": "Set a finding as NOTIFIED"
        }
      ],
      "Default": "End"
    },
    "End": {
      "Type": "Pass",
      "End": true
    },
    "Set a finding as NOTIFIED": {
      "Type": "Task",
      "Parameters": {
        "FindingIdentifiers": [
          {
            "Id.$": "$.detail.findings[0].Id",
            "ProductArn.$": "$.detail.findings[0].ProductArn"
          }
        ],
        "Workflow": {
          "Status": "NOTIFIED"
        }
      },
      "Resource": "arn:aws:states:::aws-sdk:securityhub:batchUpdateFindings",
      "Next": "End"
    }
  }
}

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.