AWS WAFでAccount Takeover Prevention (ATP)機能を使ってログインページを保護する

2022.02.15

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

いわさです。

AWS WAFの新機能としてマネージドルールにAccount Takeover Prevention(ATP)が追加されました。
この機能を使うと、盗まれた資格情報、拒否されたトークンの利用をはじめいくつかの攻撃の検知など様々なルールで認証エンドポイントへのリクエストの検査を行うことが出来ます。

本日時点で利用可能なリージョンは以下です。

  • US East (N. Virginia)
  • US West (Oregon)
  • Europe (Ireland)
  • Europe (London)
  • Asia Pacific (Singapore)

ルールが結構あるのでもう少し検証が必要な気がしていますが、まずはAPI Gatewayとルール内のひとつ「AttributeCompromisedCredentials」を使って、基本的な設定方法を確認してみました。

APIを用意

まずは保護対象のエンドポイントを用意します。
今回はAPI Gatewayでモックを作成します。特にログイン処理などは不要です。

WAF設定

AWS WAF側ではAWSManagedRulesATPRuleSetがマネージドルールに追加されていますので、有効化します。

AWS WAF Fraud Control account takeover prevention (ATP) rule group - AWS WAF, AWS Firewall Manager, and AWS Shield Advanced

このルールでは認証リクエストを検査するため、どのエンドポイントのペイロードのどの部分を対象とするか指定し、ACLをAWSリソースへ関連付けする必要があります。

ここでは、先程作成したAPI Gatewayリソースを関連付けし、loginエンドポイントを指定しました。

上記ではシミュレーション用に盗まれた資格情報として使える組合せが2つ紹介されています。

  • WAF_TEST_CREDENTIAL / WAF_TEST_CREDENTIAL_PASSWORD
  • WAF_TEST_CREDENTIAL@wafexample.com / WAF_TEST_CREDENTIAL_PASSWORD

こちらを使ってPOST送信し、WAFのログを確認してみます。

{
    "timestamp": 1644877553536,
    "formatVersion": 1,
    "webaclId": "arn:aws:wafv2:us-east-1:123456789012:regional/webacl/hoge-atp/fc7505b2-90be-4326-a80b-e1edd6a58602",
    "terminatingRuleId": "Default_Action",
    "terminatingRuleType": "REGULAR",
    "action": "ALLOW",
    "terminatingRuleMatchDetails": [],
    "httpSourceName": "APIGW",
    "httpSourceId": "123456789012:6nqrjjgxeh:iwasa",
    "ruleGroupList": [
        {
            "ruleGroupId": "AWS#AWSManagedRulesATPRuleSet",
            "terminatingRule": null,
            "nonTerminatingMatchingRules": [],
            "excludedRules": null
        }
    ],
    "rateBasedRuleList": [],
    "nonTerminatingMatchingRules": [],
    "requestHeadersInserted": null,
    "responseCodeSent": null,
    "httpRequest": {
        "clientIp": "xxx.xxx.xxx.xxx",
        "country": "JP",
        "headers": [
            {
                "name": "X-Forwarded-For",
                "value": "xxx.xxx.xxx.xxx"
            },
            {
                "name": "X-Forwarded-Proto",
                "value": "https"
            },
            {
                "name": "X-Forwarded-Port",
                "value": "443"
            },
            {
                "name": "Host",
                "value": "6nqrjjgxeh.execute-api.us-east-1.amazonaws.com"
            },
            {
                "name": "X-Amzn-Trace-Id",
                "value": "Root=1-620ad6f1-510e2cfe4e8d990310cf22a6"
            },
            {
                "name": "Content-Length",
                "value": "43"
            },
            {
                "name": "user-agent",
                "value": "curl/7.64.1"
            },
            {
                "name": "accept",
                "value": "*/*"
            },
            {
                "name": "content-type",
                "value": "application/json"
            }
        ],
        "uri": "/iwasa/login",
        "args": "",
        "httpVersion": "HTTP/1.1",
        "httpMethod": "POST",
        "requestId": "NjaFwGL3IAMFTvQ="
    },
    "labels": [
        {
            "name": "awswaf:managed:aws:atp:signal:credential_compromised"
        }
    ]
}

ラベルがセットされていますね。
このマネージドルールでは検査結果として各種ラベルを付与してくれます。

あとはラベル一致ルールなどを使ってブロックなどを設定して使う形ですね。

ここではawswaf:managed:aws:atp:signal:credential_compromisedラベル付与時にブロックしてみました。

ブロックルールを設定し動作確認

ではブロックルールを設定した状態でいくつかリクエストパターンをためしてみましょう。

//ブロックされない認証情報
$ curl -X POST -H "Content-Type: application/json" -d '{"username":"iwasa", "password":"password"}' https://6nqrjjgxeh.execute-api.us-east-1.amazonaws.com/iwasa/login
mock post

//ブロックされる認証情報
$ curl -X POST -H "Content-Type: application/json" -d '{"username":"WAF_TEST_CREDENTIAL", "password":"WAF_TEST_CREDENTIAL_PASSWORD"}' https://6nqrjjgxeh.execute-api.us-east-1.amazonaws.com/iwasa/login
atp by waf!!!

//ブロックされる認証情報だが、対象ではないURL
$ curl -X POST -H "Content-Type: application/json" -d '{"username":"WAF_TEST_CREDENTIAL", "password":"WAF_TEST_CREDENTIAL_PASSWORD"}' https://6nqrjjgxeh.execute-api.us-east-1.amazonaws.com/iwasa/nologin
nologin mock post

指定したエンドポイントのシミュレーション用資格情報でのみ、ブロックされカスタムレスポンスが返ってきましたね。

さいごに

まずは、credential_compromisedだけですが、ブロック設定する形でためしてみました。
割と気軽に使えています。東京リージョンでも使えるようになってほしいですね。

他には、アプリケーション用のSDKも提供されているようです。
ドキュメントでは以下のように記載がありましたが、マネージメントコンソールからダウンロードして使うことが出来そうでした。
こちらもためしてみようと思います。

AWS WAF also offers custom SDKs for Android and iOS mobile apps. For access to the mobile SDKs, contact sales at Contact AWS.

AWS WAF client application integration - AWS WAF, AWS Firewall Manager, and AWS Shield Advanced

また、他のルールと同様に、本番では事前にカウントモードでのルールのテストと調整は必要ですね。
ドキュメント上でも以下のように案内されていました。

Before you deploy your ATP implementation for production traffic, test and tune it in a staging or testing environment until you are comfortable with the potential impact to your traffic. Then test and tune the rules in count mode with your production traffic before enabling them.