ちょっと話題の記事

[新機能]AWS WAFマネージドルールで誤検知対応できる例外ルールの設定が可能になりました

AWS WAFマネージドルールに例外ルールの設定が追加されました。これにより、これまでオンオフの切り替えしか出来なかったマネージドルールを一部のルールだけ無効にすることが可能となりました。設定方法についても解説します。
2018.12.24

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

こんにちは、臼田です。

皆さんWAFWAFしていますか?(久しぶり)

今回はAWS WAFマネージドルールに待望の例外ルール設定を行うことができるようになりましたのでこちらを紹介します。

Announcing rule group exception for Managed Rules for AWS WAF

これまでの誤検知対策

AWS WAFマネージドルールは大変便利な機能で、メンテナンスが大変なAWS WAFのルールをサードパーティのセキュリティベンダーが面倒を見てくれる素晴らしいものです。

しかしながら、提供されるルールがブラックボックスであったため、誤検知が起きた際に対処がしづらいという欠点もありました。

具体的には下記のように、誤検知となるクエリのパターンをログ等から分析して、そのパターンを例外登録する必要がありました。

AWS WAFマネージドルールで誤検知した場合の対処法

例外ルール設定とは

セキュリティベンダーから提供されるマネージドルールは、ルールグループという複数のルールを束ねたものとなっています。この内、指定したルールのみを例外ルールとして登録することが可能になりました。

例外ルールは複数設定することもできます。

ルールの指定はRuleIdを利用して行います。RuleId自体は、ログから特定する必要があります。

これまでも誤検知を解消するためにはログから確認していましたが、ルールの中身の条件がわからなかったため、誤検知を回避するためのルール作成が難しかったです。

その点が解消されます。

やってみた

まずは誤検知を起こしているRuleIdを特定します。

時刻やリクエスト内容などの条件によりログをクエリしてください。

ログ自体の取得、クエリ方法は下記を参照してください。

AWS WAFのフルログをAthenaで分析できるようにしてみた

誤検知を起こしているということは、BLOCKかCOUNTとなっているはずなので、上記記事のBLOCKのログCOUNTのログ項あたりが参考になるかと思います。

ログの内容は下記のようになります。

BLOCKの場合

BLOCKしている場合に、該当するRuleIdはruleGroupListの中のterminatingRuleに含まれるruleIdになります。

{
	"timestamp": 1545597237187,
	"formatVersion": 1,
	"webaclId": "d7e7af02-****-****-****-************",
	"terminatingRuleId": "be06c7bc-****-****-****-************",
	"terminatingRuleType": "GROUP",
	"action": "BLOCK",
	"httpSourceName": "ALB",
	"httpSourceId": "app/test-alb/0000000000000000",
	"ruleGroupList": [
		{
			"ruleGroupId": "be06c7bc-****-****-****-************",
			"terminatingRule": {
				"ruleId": "68661648-****-****-****-************",
				"action": "BLOCK"
			},
			"nonTerminatingMatchingRules": [],
			"excludedRules": null
		}
	],
	"rateBasedRuleList": [],
	"nonTerminatingMatchingRules": [],
	"httpRequest": {
		"clientIp": "xx.xx.xx.xx",
		"country": "JP",
		"headers": [
			{
				"name": "Host",
				"value": "test-alb-000000000.ap-northeast-1.elb.amazonaws.com"
			},
			{
				"name": "Content-Length",
				"value": "28"
			},
			{
				"name": "User-Agent",
				"value": "curl/7.54.0"
			},
			{
				"name": "Accept",
				"value": "*/*"
			},
			{
				"name": "Content-Type",
				"value": "application/x-www-form-urlencoded"
			}
		],
		"uri": "/wordpress/",
		"args": "id=1",
		"httpVersion": "HTTP/1.1",
		"httpMethod": "POST",
		"requestId": null
	}
}

COUNTの場合

COUNTの場合もBLOCKと同じものが該当のRuleIdです。COUNTではnonTerminatingMatchingRulesにCOUNTとなったRuleIdが出力されますが、これはRuleGroupIdとなっているため間違えないようにする必要があります。

{
	"timestamp": 1545597243349,
	"formatVersion": 1,
	"webaclId": "d7e7af02-****-****-****-************",
	"terminatingRuleId": "Default_Action",
	"terminatingRuleType": "REGULAR",
	"action": "ALLOW",
	"httpSourceName": "ALB",
	"httpSourceId": "app/test-alb/0000000000000000",
	"ruleGroupList": [
		{
			"ruleGroupId": "be06c7bc-****-****-****-************",
			"terminatingRule": {
				"ruleId": "68661648-****-****-****-************",
				"action": "BLOCK"
			},
			"nonTerminatingMatchingRules": [],
			"excludedRules": null
		}
	],
	"rateBasedRuleList": [],
	"nonTerminatingMatchingRules": [
		{
			"ruleId": "be06c7bc-****-****-****-************",
			"action": "COUNT"
		}
	],
	"httpRequest": {
		"clientIp": "xx.xx.xx.xx",
		"country": "JP",
		"headers": [
			{
				"name": "Host",
				"value": "test-alb-000000000.ap-northeast-1.elb.amazonaws.com"
			},
			{
				"name": "Content-Length",
				"value": "28"
			},
			{
				"name": "User-Agent",
				"value": "curl/7.54.0"
			},
			{
				"name": "Accept",
				"value": "*/*"
			},
			{
				"name": "Content-Type",
				"value": "application/x-www-form-urlencoded"
			}
		],
		"uri": "/wordpress/",
		"args": "id=1",
		"httpVersion": "HTTP/1.1",
		"httpMethod": "POST",
		"requestId": null
	}
}

例外ルール設定

例外ルール設定はWebACLの設定画面から行います。

WebACLを選択しRulesタブからEdit web ACLを押します。ちなみに、例外ルール設定の表示項目が下部に追加されています。

設定ページでも下部にexceptionsが追加されています。まず右側の開く矢印を押します。

次にテキストボックスに例外とするRuleIdを入力して、右側の+を押します。(そのままUpdateを押さない)

複数例外を登録する場合はこれを繰り返します。

その後Updateを押して設定完了です。

設定後の動作

設定後には、ルールが無視されていることがログにも出るようになり、そのためログのスキーマも拡張されています。

ruleGroupList内にexcludedRulesが含まれるようになっています。

詳細は下記を参照してください。

Logging Web ACL Traffic Information - AWS WAF, AWS Firewall Manager, and AWS Shield Advanced

これに合わせてAthenaの定義も変える必要があります。下記を更新しましたのでお使いください。

AWS WAFのフルログをAthenaで分析できるようにしてみた

ログは下記のように変わっています。

{
	"timestamp": 1545599375134,
	"formatVersion": 1,
	"webaclId": "d7e7af02-****-****-****-************",
	"terminatingRuleId": "Default_Action",
	"terminatingRuleType": "REGULAR",
	"action": "ALLOW",
	"httpSourceName": "ALB",
	"httpSourceId": "app/test-alb/0000000000000000",
	"ruleGroupList": [
		{
			"ruleGroupId": "be06c7bc-****-****-****-************",
			"terminatingRule": null,
			"nonTerminatingMatchingRules": [],
			"excludedRules": [
				{
					"ExclusionType": "EXCLUDED_AS_COUNT",
					"ruleId": "68661648-****-****-****-************"
				}
			]
		}
	],
	"rateBasedRuleList": [],
	"nonTerminatingMatchingRules": [],
	"httpRequest": {
		"clientIp": "xx.xx.xx.xx",
		"country": "JP",
		"headers": [
			{
				"name": "Host",
				"value": "test-alb-000000000.ap-northeast-1.elb.amazonaws.com"
			},
			{
				"name": "Content-Length",
				"value": "28"
			},
			{
				"name": "User-Agent",
				"value": "curl/7.54.0"
			},
			{
				"name": "Accept",
				"value": "*/*"
			},
			{
				"name": "Content-Type",
				"value": "application/x-www-form-urlencoded"
			}
		],
		"uri": "/wordpress/",
		"args": "id=1",
		"httpVersion": "HTTP/1.1",
		"httpMethod": "POST",
		"requestId": null
	}
}

excludedRulesに指定したRuleIdが入っており、前回と同じ条件でALLOWとなっていることが確認できました。

まとめ

AWS WAFマネージドルールに例外ルールの設定が可能となりました。

この設定の場合は、手動で例外ルールを作成してを登録していた場合と違い、一括で該当ルールが無効になるため、一部のページのみ無効というようなことは出来ません。そのようなケースでは引き続き手動で登録する必要はあります。

また、依然としてマネージドルール自体はブラックボックスなため、RuleIdのみでしか識別できず少しやりづらいところはありますが、Ruleの中身は各セキュリティベンダーのノウハウが詰まっているため、このあたりが落とし所なのかと思います。

マネージドルールは費用対効果のいいサービスだと思うので、誤検知が懸念で導入を断念していた方は、是非これを機に使ってみてはいかがでしょうか?