ウェブサイトでのアカウント関連の不正行為の検出と防止

このドキュメントでは、アカウント保護を使用して、ウェブサイトでのアカウント関連の不正行為を検出して防止する方法について説明します。

Fraud Defense は、ログインや購入手続きなど、重要なアクションの保護に役立ちます。ただし、ウェブサイトでの特定のユーザーの行動を一定期間にわたって観察することで検出できる、アカウントの不正使用の微妙な形態は多数存在します。Fraud Defense の機能であるアカウント防御は、ウェブサイトのサイト固有のモデルを作成して、疑わしい行動の傾向やアクティビティの変化を検出することで、このような微妙な不正行為を特定するのに役立ちます。サイト固有のモデルを使用すると、アカウント防御によって次の検出が容易になります。

  • 不審なアクティビティ
  • 類似した動作のアカウント
  • 特定のユーザーに対して信頼できるとマークされたデバイスからのリクエスト

アカウント保護機能とサイト固有のモデルの分析に基づいて、次のことを行えます。

  • 不正なアカウントを制限または無効にする。
  • アカウントの乗っ取りの試みを防ぐ。
  • 正常なアカウントの乗っ取りを軽減する。
  • 正当なユーザー アカウントからのリクエストにのみアクセスを許可する。
  • 信頼できるデバイスからのユーザー ログインをスムーズにする。

始める前に

  1. reCAPTCHA 用に環境を準備します
  2. スコアベースのサイトキーを作成します

アカウント防御用にウェブページを構成する

アカウント保護では、効果的な検出を可能にするために、アカウント アクティビティを包括的に理解する必要があります。アカウント関連のアクティビティをアカウント防御にフィードし、サイト固有のモデルを作成して改善するには、次の手順を行います。

  1. 水平テレメトリー データの収集を有効にする
  2. 重要なユーザー アクションに関するレポートを行う
  3. 重要なユーザー イベントを評価する
  4. ユーザー イベントにアノテーションを付け、サイト固有のモデルを調整する

水平テレメトリー データの収集を有効にする

アカウント保護では、ユーザーがログインしているか、あるいはログインしようとしているかなど、ユーザーの操作をすべて確認できます。アカウント防御による水平テレメトリー データのパッシブ収集を有効にするには、ユーザーワークフローの一部であるすべてのウェブページのバックグラウンドで作成したスコアベースのサイトキーを使用して、reCAPTCHA JavaScript のスクリプトを読み込みます。

次の例では、reCAPTCHA JavaScript のスクリプトをウェブページに読み込む方法を示します。

    <head>
    <script src="https://www.google.com/recaptcha/enterprise.js?render=KEY_ID"></script>
    ....
    </head>

重要なユーザー アクションに関するレポートを行う

不審なアクティビティのパターンを検出し、サイトの一般的なアクティビティ パターンのより優れたモデルを構築するには、アカウント防御で重要なユーザー アクションに関する情報が必要です。したがって、これらの重要なユーザー アクションに対して grecaptcha.enterprise.execute() を呼び出して、ウェブページで重要なユーザー アクションのレポートを行います。

追加のシグナルの収集に役立つため、重要なユーザー アクションをすべてレポートすることをおすすめします。レポートするユーザー アクションごとに、grecaptcha.enterprise.execute()action パラメータの値を、ユーザー アクションを表すアクション名に置き換えます。

次の表に、重要なユーザー アクションをレポートする際に使用できるアクション名を示します。

アクション名 ユーザーが開始したイベントまたはユーザー アクション
LOGIN

ウェブサイトへのログイン。

REGISTRATION ウェブサイトでの登録。
SECURITY_QUESTION_CHANGE セキュリティ保護用の質問を変更するためのリクエスト。
PASSWORD_RESET パスワード再設定のリクエスト。
PHONE_NUMBER_UPDATE 電話番号の更新のリクエスト。
EMAIL_UPDATE メールアドレスの更新のリクエスト。
ACCOUNT_UPDATE 連絡先情報など、アカウントの関連情報の更新のリクエスト。
TRIGGER_MFA MFA チャレンジをトリガーするアクション。
REDEEM_CODE コードの利用のリクエスト。
LIST_PAYMENT_METHODS お支払い方法のリストの取得。

次の例では、電話番号の更新で grecaptcha.enterprise.execute() を呼び出す方法を示します。

    <script>
    function onClick(e) {
      e.preventDefault();
      grecaptcha.enterprise.ready(async () => {
        const token = await grecaptcha.enterprise.execute('KEY_ID', {action: 'PHONE_NUMBER_UPDATE'});
      });
    }
    </script>
    

重要なユーザー イベントを評価する

ユーザー アクションで grecaptcha.enterprise.execute() を呼び出すと、トークンが生成されます。ログインの成功 / 失敗、登録、ログインしているユーザーのアクションなどの重要なユーザー イベントについては、grecaptcha.enterprise.execute() 呼び出しの結果を診断する評価を作成します。この評価によって、起こり得る不正行為の処理方法を決定する際の基準となるリスク判定が得られます。実行できるアクションには、不審なリクエストのブロック、リスクの高いログインへの疑い、関心のあるアカウントの調査などがあります。

アカウント保護機能では、評価を行い、ユーザー アクティビティ(ログイン リクエスト、ログイン済みリクエスト、登録リクエストなど)を特定のアカウントに関連付けるために、安定したアカウント ID を指定する必要があります。これにより、アカウント保護機能では、ユーザー アクティビティ パターンを処理して、アカウントごとにアクティビティ モデルを構築し、異常なトラフィックや不正なトラフィックをより適切に検出できます。

ユーザーが頻繁に変更しない固定のアカウント ID accountId を選択し、 projects.assessments.create メソッドで評価を指定します。この固定アカウント ID は、同じユーザーに関連するすべてのイベントで同じ値にする必要があります。アカウント ID として、以下を指定できます。

ユーザー識別子

すべてのアカウントを、固定のユーザー名、メールアドレス、電話番号に一意に関連付けることができる場合は、accountId として使用できます。このようなクロスサイト ID(サイト間で再利用できる ID)を指定すると、reCAPTCHA はこの情報を使用して、不正なアカウント ID にフラグを立て、こうした識別子に関連するクロスサイト不正行為のパターンに関する知識を活用することで、クロスサイト モデルに基づいてユーザー アカウントの保護を強化します。

あるいは、各アカウントに一意に関連付けられた内部ユーザー ID がある場合は、それを accountId として指定できます。

ハッシュ化と暗号化

各アカウントに一意に関連付けられた内部ユーザー ID がない場合は、安定した識別子を不透明なサイト固有のアカウント識別子にできます。この識別子は、reCAPTCHA のアカウント保護機能がユーザー アクティビティ パターンを把握して異常な動作を検出するために引き続き必要ですが、他のサイトと共有されることはありません。

任意の固定アカウント ID を選び、暗号化またはハッシュ化を使用して、reCAPTCHA に送信する前に不透明化します。

  • 暗号化(推奨):安定した暗号テキストを生成する決定的な暗号化方法を使用して、アカウント ID を暗号化します。詳細な手順については、データを確定的に暗号化するをご覧ください。ハッシュ化ではなく対称暗号化を選択した場合、ユーザー ID と対応する不透明なユーザー ID とのマッピングを維持する必要はありません。reCAPTCHA から返される不透明な ID を復号して、ユーザー ID に変換します。

  • ハッシュ化: SHA256-HMAC メソッドを使用して、任意のカスタム ソルトでアカウント ID をハッシュ化することをおすすめします。ハッシュは一方向のため、生成されたハッシュとユーザー ID の間のマッピングを維持する必要があります。これにより、元のアカウントに返されるハッシュ化されたアカウント ID をマッピングできます。

アカウント関連のすべてのリクエストに安定したアカウント ID を提供するだけでなく、一部の特定のリクエストには変更できない可能性のある追加アカウント ID を指定できます。accountId に加えて提供されるコンテキスト固有のアカウント ID は、アカウント保護がユーザー アクティビティをより深く分析し、ユーザー アカウントを安全に保つためのアカウントの乗っ取りの試みを検出するのに役立ちます。追加の ID を指定すると、Google Cloud Fraud Defense はこの情報を使用して、不正なアカウント ID にフラグを立て、これらの識別子に関連するクロスサイトへの不正行為パターンの知識を活用することで、クロスサイト モデルに基づいてユーザー アカウントの保護を強化します。たとえば、次の情報を提供できます。

  • ログイン リクエストのログイン ハンドルとして使用されたユーザー名、メールアドレス、電話番号

  • 多要素認証リクエスト用の確認済みのメールアドレスまたは電話番号

  • アカウントの更新リクエスト時にユーザーから提供されたメールアドレスまたは電話番号(メインまたはサブ)

  • 登録リクエスト時にユーザーから提供されたメールアドレスと電話番号

選択した安定したアカウント ID を、アカウント関連のすべてのリクエストの projects.assessments.create メソッドの accountId パラメータに追加します。必要に応じて、評価の userIds フィールドを使用して、関連するリクエストの追加アカウント ID を指定します。

リクエストのデータを使用する前に、次のように置き換えます。

  • PROJECT_ID: 実際の Google Cloud プロジェクト ID
  • TOKEN: grecaptcha.enterprise.execute() 呼び出しから返されたトークン
  • KEY_ID: サイトに関連付けられている reCAPTCHA キー
  • ACCOUNT_ID: ユーザー アカウントとウェブサイトの関連付けのためにユーザー アカウントに一意に関連付けられた不透明な識別子
  • EMAIL_ADDRESS: 省略可。このリクエストに関連付けられているメールアドレス(該当する場合)
  • PHONE_NUMBER: 省略可。このリクエストに関連付けられている電話番号(該当する場合)
  • USERNAME: 省略可。このリクエストに関連付けられているユーザー名(該当する場合)

HTTP メソッドと URL:

POST https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments

リクエストの本文(JSON):

{
  "event": {
    "token": "TOKEN",
    "siteKey": "KEY_ID",
    "userInfo": {
      "accountId": "ACCOUNT_ID",
      "userIds": [
        {
          "email": "EMAIL_ADDRESS"
        },
        {
          "phoneNumber": "PHONE_NUMBER"
        },
        {
          "username": "USERNAME"
        }
      ]
    }
  }
}

リクエストを送信するには、次のいずれかのオプションを選択します。

curl

リクエスト本文を request.json という名前のファイルに保存して、次のコマンドを実行します。

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments"

PowerShell

リクエスト本文を request.json という名前のファイルに保存して、次のコマンドを実行します。

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments" | Select-Object -Expand Content

次のような JSON レスポンスが返されます。

{
  "tokenProperties": {
    "valid": true,
    "hostname": "www.google.com",
    "action": "login",
    "createTime": "2019-03-28T12:24:17.894Z"
  },
  "riskAnalysis": {
    "score": 0.6,
  },
  "event": {
    "token": "TOKEN",
    "siteKey": "KEY",
    "userInfo": {
      "accountId": "ACCOUNT_ID"
    }
  },
  "name": "projects/PROJECT_NUMBER/assessments/b6ac310000000000",
  "accountDefenderAssessment": {
    "labels": ["SUSPICIOUS_LOGIN_ACTIVITY"]
  }
}

コードサンプル

Java

Fraud Defense に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。


import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient;
import com.google.protobuf.ByteString;
import com.google.recaptchaenterprise.v1.AccountDefenderAssessment.AccountDefenderLabel;
import com.google.recaptchaenterprise.v1.Assessment;
import com.google.recaptchaenterprise.v1.CreateAssessmentRequest;
import com.google.recaptchaenterprise.v1.Event;
import com.google.recaptchaenterprise.v1.ProjectName;
import com.google.recaptchaenterprise.v1.RiskAnalysis.ClassificationReason;
import com.google.recaptchaenterprise.v1.TokenProperties;
import com.google.recaptchaenterprise.v1.UserId;
import com.google.recaptchaenterprise.v1.UserInfo;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AccountDefenderAssessment {

  public static void main(String[] args)
      throws IOException, NoSuchAlgorithmException, InvalidKeyException {
    // TODO(developer): Replace these variables before running the sample.
    // projectId: Google Cloud Project ID
    String projectId = "project-id";

    // recaptchaSiteKey: Site key obtained by registering a domain/app to use recaptcha
    // services.
    String recaptchaSiteKey = "recaptcha-site-key";

    // token: The token obtained from the client on passing the recaptchaSiteKey.
    // To get the token, integrate the recaptchaSiteKey with frontend. See,
    // https://cloud.google.com/recaptcha-enterprise/docs/instrument-web-pages#frontend_integration_score
    String token = "recaptcha-token";

    // recaptchaAction: The action name corresponding to the token.
    String recaptchaAction = "recaptcha-action";

    // Unique ID of the user, such as email, customer ID, etc.
    String accountId = "default" + UUID.randomUUID().toString().split("-")[0];

    // User phone number
    String phoneNumber = "555-987-XXXX";

    // User email address
    String emailAddress = "john.doe@example.com";

    accountDefenderAssessment(projectId, recaptchaSiteKey, token, recaptchaAction, accountId, phoneNumber, emailAddress);
  }

  /**
   * This assessment detects account takeovers. See,
   * https://cloud.google.com/recaptcha-enterprise/docs/account-takeovers The input is the hashed
   * account id. Result tells if the action represents an account takeover. You can optionally
   * trigger a Multi-Factor Authentication based on the result.
   */
  public static void accountDefenderAssessment(
      String projectId,
      String recaptchaSiteKey,
      String token,
      String recaptchaAction,
      String accountId,
      String phoneNumber,
      String emailAddress)
      throws IOException {
    try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {

      // Set the properties of the event to be tracked.
      Event.Builder eventBuilder =
          Event.newBuilder()
              .setSiteKey(recaptchaSiteKey)
              .setToken(token);

      // Set the account id, email address and phone number (of the user).
      eventBuilder.setUserInfo(
        UserInfo.newBuilder()
          .setAccountId(accountId)
          .addUserIds(UserId.newBuilder().setEmail(emailAddress))
          .addUserIds(UserId.newBuilder().setPhoneNumber(phoneNumber)));

      Event event = eventBuilder.build();

      // Build the assessment request.
      CreateAssessmentRequest createAssessmentRequest =
          CreateAssessmentRequest.newBuilder()
              .setParent(ProjectName.of(projectId).toString())
              .setAssessment(Assessment.newBuilder().setEvent(event).build())
              .build();

      Assessment response = client.createAssessment(createAssessmentRequest);

      // Check integrity of the response token.
      if (!checkTokenIntegrity(response.getTokenProperties(), recaptchaAction)) {
        return;
      }

      // Get the reason(s) and the reCAPTCHA risk score.
      // For more information on interpreting the assessment,
      // see: https://cloud.google.com/recaptcha-enterprise/docs/interpret-assessment
      for (ClassificationReason reason : response.getRiskAnalysis().getReasonsList()) {
        System.out.println(reason);
      }
      float recaptchaScore = response.getRiskAnalysis().getScore();
      System.out.println("The reCAPTCHA score is: " + recaptchaScore);
      String assessmentName = response.getName();
      System.out.println(
          "Assessment name: " + assessmentName.substring(assessmentName.lastIndexOf("/") + 1));

      // Get the Account Defender result.
      com.google.recaptchaenterprise.v1.AccountDefenderAssessment accountDefenderAssessment =
          response.getAccountDefenderAssessment();
      System.out.println(accountDefenderAssessment);

      // Get Account Defender label.
      List<AccountDefenderLabel> defenderResult =
          response.getAccountDefenderAssessment().getLabelsList();
      // Based on the result, can you choose next steps.
      // If the 'defenderResult' field is empty, it indicates that Account Defender did not have
      // anything to add to the score.
      // Few result labels: ACCOUNT_DEFENDER_LABEL_UNSPECIFIED, PROFILE_MATCH,
      // SUSPICIOUS_LOGIN_ACTIVITY, SUSPICIOUS_ACCOUNT_CREATION, RELATED_ACCOUNTS_NUMBER_HIGH.
      // For more information on interpreting the assessment, see:
      // https://cloud.google.com/recaptcha-enterprise/docs/account-defender#interpret-assessment-details
      System.out.println("Account Defender Assessment Result: " + defenderResult);
    }
  }

  private static boolean checkTokenIntegrity(
      TokenProperties tokenProperties, String recaptchaAction) {
    // Check if the token is valid.
    if (!tokenProperties.getValid()) {
      System.out.println(
          "The Account Defender Assessment call failed because the token was: "
              + tokenProperties.getInvalidReason().name());
      return false;
    }

    // Check if the expected action was executed.
    if (!tokenProperties.getAction().equals(recaptchaAction)) {
      System.out.printf(
          "The action attribute in the reCAPTCHA tag '%s' does not match "
              + "the action '%s' you are expecting to score",
          tokenProperties.getAction(), recaptchaAction);
      return false;
    }
    return true;
  }
}

重要なユーザー イベントのリスク判定を解釈する

アカウント防御を有効にして評価を作成すると、アカウント防御は評価レスポンスの一部として accountDefenderAssessment を返します。accountDefenderAssessment の値は、ユーザーのアクションが正当か不正かを判断するのに役立ちます。また、ユーザー イベントにアノテーションを付ける際に使用する必要がある評価 ID も返します。

次の例は、JSON レスポンスのサンプルです。

{
  "tokenProperties": {
    "valid": true,
    "hostname": "www.google.com",
    "action": "login",
    "createTime": "2019-03-28T12:24:17.894Z"
   },
  "riskAnalysis": {
    "score": 0.6,
  },
 "event": {
    "token": "TOKEN",
    "siteKey": "KEY_ID",
    "expectedAction": "USER_ACTION"
  },
  "name": "projects/PROJECT_ID/assessments/b6ac310000000000X",
  "accountDefenderAssessment": {
    labels: ["SUSPICIOUS_LOGIN_ACTIVITY"]
  }
}

accountDefenderAssessment フィールドは次のいずれかの値になります。

説明
SUSPICIOUS_LOGIN_ACTIVITY リクエストが、クレデンシャル スタッフィングまたはアカウントの乗っ取りのリスクが高いことを示します。
SUSPICIOUS_ACCOUNT_CREATION リクエストが、悪用されたアカウント作成のリスクが高いことを示します。
PROFILE_MATCH

ユーザーの属性が、この特定のユーザーの以前に確認された属性に一致することを示します。この値は、このユーザーが以前ウェブサイトにアクセスするために使用した信頼できるデバイス上にいることを示します。

PROFILE_MATCH は、次のシナリオでのみ返されます。

  • 多要素(MFA)または 2 要素認証(2FA)を使用し、ユーザーが MFA チャレンジまたは 2FA チャレンジに合格したら、アカウント保護機能でユーザー プロファイルを信頼できるとしてマークします。
  • 評価に LEGITIMATE または PASSED_TWO_FACTOR アノテーションを付け、アカウント保護は対応するユーザー プロファイルを信頼できるとしてマークします。
RELATED_ACCOUNTS_NUMBER_HIGH リクエストに多数の関連アカウントがあることを示します。必ずしもアカウントが不正であることを意味するわけではありませんが、さらなる調査が必要になる場合があります。

イベントにアノテーションを付け、サイト固有のモデルを調整する

アカウント保護に詳細情報を提供し、サイト固有の検出モデルを改善するには、評価を作成して評価したイベントにアノテーションを付ける必要があります。

評価にアノテーションを付けるには、評価 ID を使用して projects.assessments.annotate メソッドにリクエストを送信します。リクエストの本文には、評価で説明されているイベントに関する追加情報を提供するラベルを含めます。

評価にアノテーションを付けるには、次のようにします。

  1. ユースケースに応じて、リクエストの JSON 本文に追加する情報とラベルを決定します。

    次の表では、イベントにアノテーションを付けるために使用できるラベルと値を示します。

    ラベル 説明 リクエストの例
    reasons 必須。評価をサポートするラベル。

    リアルタイムの検出に影響するため、イベント後数秒または数分で reasons ラベルにリアルタイムのイベントの詳細が提供されます。

    有効な値については、理由の値をご覧ください。

    例: アカウントの乗っ取りを検出するには、入力したパスワードが正しいかどうかを CORRECT_PASSWORD または INCORRECT_PASSWORD の値でアノテーションを設定します。独自の MFA をデプロイした場合は、INITIATED_TWO_FACTORPASSED_TWO_FACTORFAILED_TWO_FACTOR の値を追加できます。

          {
          "reasons": ["INCORRECT_PASSWORD"]
          }
        
    annotation 省略可。評価の正当性を示すラベル。

    annotation ラベルで、ログイン イベントと登録イベントに関する事実を提供して、リスク評価を検証または修正します。

    有効な値は LEGITIMATE または FRAUDULENT です。

    この情報はいつでも送信でき、またバッチジョブの一部として送信できます。 ただし、リアルタイムの検出に影響するため、この情報はイベント後数秒または数分で送信することをおすすめします。

          {
           "annotation": "LEGITIMATE"
          }
    
      
    accountId

    省略可。アカウント ID をイベントに関連付けるラベル。

    アカウント ID なしで評価を作成した場合は、イベントのアカウント ID を提供するために、利用可能な場合はこのラベルを使用します。

      {
       "accountId": "ACCOUNT_ID"
      }
  2. 適切なラベルを使用してアノテーション リクエストを作成します。

    リクエストのデータを使用する前に、次のように置き換えます。

    • ASSESSMENT_ID: projects.assessments.create 呼び出しから返された name フィールドの値。
    • ANNOTATION: 省略可。評価が正当か不正かを示すラベル。
    • REASONS: 省略可。アノテーションをサポートする理由。有効な値については、理由の値をご覧ください。
    • ACCOUNT_ID: 省略可。ウェブサイトのユーザー アカウントに一意に関連付けられた識別子。

    詳細については、アノテーションのラベルをご覧ください。

    HTTP メソッドと URL:

    POST https://recaptchaenterprise.googleapis.com/v1/ASSESSMENT_ID:annotate

    リクエストの本文(JSON):

    {
      "annotation": ANNOTATION,
      "reasons": REASONS,
      "accountId": ACCOUNT_ID
    }
    

    リクエストを送信するには、次のいずれかのオプションを選択します。

    curl

    リクエスト本文を request.json という名前のファイルに保存して、次のコマンドを実行します。

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://recaptchaenterprise.googleapis.com/v1/ASSESSMENT_ID:annotate"

    PowerShell

    リクエスト本文を request.json という名前のファイルに保存して、次のコマンドを実行します。

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://recaptchaenterprise.googleapis.com/v1/ASSESSMENT_ID:annotate" | Select-Object -Expand Content

    成功したことを示すステータス コード(2xx)と空のレスポンスが返されます。

コードサンプル

Java

Fraud Defense に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。


import com.google.cloud.recaptchaenterprise.v1.RecaptchaEnterpriseServiceClient;
import com.google.protobuf.ByteString;
import com.google.recaptchaenterprise.v1.AnnotateAssessmentRequest;
import com.google.recaptchaenterprise.v1.AnnotateAssessmentRequest.Annotation;
import com.google.recaptchaenterprise.v1.AnnotateAssessmentRequest.Reason;
import com.google.recaptchaenterprise.v1.AnnotateAssessmentResponse;
import com.google.recaptchaenterprise.v1.AssessmentName;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

public class AnnotateAccountDefenderAssessment {

  public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
    // TODO(developer): Replace these variables before running the sample.
    // projectID: GCloud Project id.
    String projectID = "project-id";

    // assessmentId: Value of the 'name' field returned from the CreateAssessment call.
    String assessmentId = "account-defender-assessment-id";

    // accountId: Set the accountId corresponding to the assessment id.
    String accountId = "default" + UUID.randomUUID().toString().split("-")[0];

    annotateAssessment(projectID, assessmentId, accountId);
  }

  /**
   * Pre-requisite: Create an assessment before annotating. Annotate an assessment to provide
   * feedback on the correctness of recaptcha prediction.
   */
  public static void annotateAssessment(
      String projectID, String assessmentId, String accountId) throws IOException {

    try (RecaptchaEnterpriseServiceClient client = RecaptchaEnterpriseServiceClient.create()) {
      // Build the annotation request.
      // For more info on when/how to annotate, see:
      // https://cloud.google.com/recaptcha-enterprise/docs/annotate-assessment#when_to_annotate
      AnnotateAssessmentRequest annotateAssessmentRequest =
          AnnotateAssessmentRequest.newBuilder()
              .setName(AssessmentName.of(projectID, assessmentId).toString())
              .setAnnotation(Annotation.LEGITIMATE)
              .addReasons(Reason.PASSED_TWO_FACTOR)
              .setAccountId(accountId)
              .build();

      // Empty response is sent back.
      AnnotateAssessmentResponse response = client.annotateAssessment(annotateAssessmentRequest);
      System.out.println("Annotated response sent successfully ! " + response);
    }
  }
}

アカウントの乗っ取りリスクスコアを使用し、解釈する

アカウントの乗っ取り(ATO)リスクスコア機能により、アカウント防御の評価に数値のリスクスコアと対人可読の説明が追加されます。これらの分析情報は、評価を理解し、その後のアクションや意思決定に役立ちます。

リスクスコアを取得する

リスクスコアと説明可能性の理由を取得するには、CreateAssessment リクエストを送信し、リクエストに event.userInfo.accountId を含めます。

リスクスコアと詳細を読む

リスクスコアと説明可能性の理由は、評価レスポンスの accountDefenderAssessment.accountTakeoverVerdict オブジェクトにあります。

  • リスクスコア: accountDefenderAssessment.accountTakeoverVerdict.risk
  • リスクの理由: accountDefenderAssessment.accountTakeoverVerdict.riskReasons
  • 信頼性の理由: accountDefenderAssessment.accountTakeoverVerdict.trustReasons

次のスニペットは、評価レスポンスのフィールドの例を示しています。

  "accountDefenderAssessment": {
    "labels": ["PROFILE_MATCH"],
    "accountTakeoverVerdict": {
      "risk": 0.249,
      "riskReasons": [{"reason": "CLIENT_ACCESSED_MANY_ACCOUNTS"}],
      "trustReasons": [{"reason": "PROFILE_MATCH"}, {"reason": "ACCOUNT_HISTORY_REPUTABLE"}]
    }
  }

ATO リスクスコアを解釈する

リスクスコアを使用する場合は、保護アクションを実行するタイミングを判断するためのしきい値を設定します。

SUSPICIOUS_LOGIN_ACTIVITY ラベルの代わりに ATO リスクスコアを使用します。同じ評価でリスクスコアとラベルの両方を使用して強制措置をトリガーしないでください。適用ロジックは、リスクスコアがしきい値を超えた場合、またはラベルが存在する場合に基づいて構成できます。一般的に、リスクスコアはより詳細な評価を提供します。

リスクスコアを適用する前に、プラットフォームのトラフィックで適切なしきい値を使用してリスクスコアのパフォーマンスを評価することをおすすめします。

リスクスコアに基づいて処理を行うには、次のスニペットに示すように、バックエンドにチェックを実装します。

if (assessment.accountDefenderAssessment.accountTakeoverVerdict.risk > YOUR_CHOSEN_THRESHOLD) {
  // Treat as suspicious
  // Implement protective actions
}

標準リスクスコアのしきい値

次の表に、標準のリスクスコアのしきい値と、想定される偽陽性率(FPR)を示します。許容可能な FPR に基づいてしきい値を選択します。パフォーマンスは変動する可能性があるため、実際のパフォーマンスに基づいてしきい値を調整する必要がある場合があります。

予想される FPR リスクスコアのしきい値
0.1% 1.0
0.25% 0.9
0.5% 0.8
1% 0.7
2% 0.6
4% 0.5
8% 0.4
15% 0.3
30% 0.2
60% 0.1
100% 0.0

しきい値を調整する

観測された FPR が高すぎる場合は、しきい値を増やします。観測された再現率が低すぎる場合、FPR の増加を許容できるのであれば、しきい値を下げます。

中間値を計算する

標準値間のしきい値の FPR を推定するには、線形補間を使用します。次の例は、しきい値 0.85 の FPR を計算する方法を示しています。

FPR(T: 0.85) = (FPR(T: 0.8) + FPR(T: 0.9)) / 2 = (0.5% + 0.25%) / 2 = 0.375%

特定の FPR のしきい値を見つけるには、標準値の間を補間します。次の例は、FPR が 5% のしきい値を求める方法を示しています。

Threshold = 0.4 + (0.5 − 0.4) × (8% − 5%) / (8% − 4%)
Threshold = 0.4 + 0.1 × (3 / 4)
Threshold = 0.4 + 0.075 = 0.475

しきい値 0.475 では、FPR が 5% になると推定されます。

説明可能性の理由を解釈する

説明可能性の理由は、リスクスコアに影響を与える要因に関する分析情報を提供します。これらの理由を参考に、意思決定を改善してください。

  • リスクの理由: アカウントの乗っ取りリスクが高まる要因を示します。
  • 信頼できる理由: 正当性を示す要因を示します。

リスクスコアには、リスクの理由と信頼の理由の両方が表示されることがあります。

理由 タイプ 解釈
PROFILE_MATCH 信頼 リクエストが、このアカウントに関連付けられている信頼できるプロファイルと一致します。これは AccountDefenderLabel.PROFILE_MATCH ラベルと同じです。
ACCOUNT_HISTORY_REPUTABLE 信頼 アカウントの過去のアクティビティが信頼できるものである。過去にアカウントが不正使用された可能性は低い。
CLIENT_HISTORICAL_BOT_ACTIVITY リスク このクライアントは過去にこのサイトにボットのようなトラフィックを送信していることが確認されています。この理由は過去の評判を反映しており、現在のリクエストが人間によって行われている場合でも、クライアントが bot を使用していることがわかっていることを示します。
ACCOUNT_IN_LARGE_RELATED_GROUP リスク アカウントが関連アカウントの大きなグループの一部である場合、不正なネットワークの一部である可能性があります。関連アカウントは、トラフィック パターンとリクエストの特性が類似していることに基づいて特定されます。
CLIENT_ACCESSED_MANY_ACCOUNTS リスク このサイトで、クライアントが多数のアカウントにアクセスしていることが確認されました。

次のステップ