WWDC Quick Look 💓 By SwiftGGTeam
Replace CAPTCHAs with Private Access Tokens

Replace CAPTCHAs with Private Access Tokens

元の動画を見る

ハイライト

CAPTCHA は、Web 上で最も迷惑なエクスペリエンスの 1 つです。これは詐欺を防ぐために存在しますが、その代償として通常のユーザー エクスペリエンスが損なわれ、プライバシーが侵害され (IP 追跡によって)、アクセシビリティの障壁が作成されます。


主要内容

CAPTCHA はサーバーの信頼性の問題を解決します。

ユーザーがアカウントを登録したり、アカウントにログインしたり、商品を購入したりするとき、サーバーは、そのリクエストが通常のユーザーからのものなのか、攻撃者やボットからのものなのかを判断する必要があります。従来のアプローチでは、CAPTCHA をポップアップして、ユーザーが追加のチャレンジを完了できるようにします。

問題は、このチャレンジが通常のユーザーの邪魔をすることです。スピーチは、Financial Times へのログインの例から始まりました。iOS 15 では、同じログイン プロセスで CAPTCHA が発生します。プライベート アクセス トークンをサポートする iOS 16 では、ユーザーは Web サイトに直接アクセスできます (04:09)。

CAPTCHA にはさらに 2 つの問題があります。クライアントが信頼できるかどうかを判断するために、多くのサービスは IP アドレスの追跡またはフィンガープリンティングに依存しています。これは、Safari、メール プライバシー保護、および iCloud プライベート リレーのプライバシーに関する方針と矛盾します。CAPTCHA は、障害や言語の壁を持つ実際のユーザーもブロックします (02:04)。

プライベート アクセス トークンは、これをシステム レベルの証明に変えます。サーバーはユーザーに質問への回答を求めることはなくなり、代わりに iOS 16 または macOS Ventura を使用するクライアントが、実際の Apple デバイスからのものであること、デバイスのロックが解除されていること、ユーザーが Apple ID でサインインしていること、リクエストが署名済みのアプリまたは Safari/WebKit からのものであることを自動的に証明できるようになります (02:46)。

この証明によって、ユーザーの身元が Web サイトに引き渡されることはありません。Apple は、IETF プライバシー パス ワーキング グループによって標準化されているプロトコルを使用し、RSA ブラインド署名を使用してトークンを無相関にします。サーバーはトークンが有効であることを確認することしかできませんが、ユーザーを特定することはできません。また、トークンを使用してユーザーを長時間追跡することもできません (04:44)。


詳細

プロトコル: サーバーが PrivateToken チャレンジを開始します

(05:02) プライベート アクセス トークンは、HTTP 認証チャレンジから始まります。サーバーが戻りますPrivateToken認証スキームを選択し、信頼するトークン発行者を指定します。

このセッションには公式のコード スニペットはありません。以下は、プロトコル フィールドの場所を示すために、逐語的なドラフトからコンパイルされた概念的な HTTP インタラクションです。特定の形式は、選択した発行者のドキュメントに基づく必要があります。

HTTP/1.1 401 Unauthorized
WWW-Authenticate: PrivateToken issuer="https://issuer.example"

キーポイント:

  • 行 1: サーバーは 401 で応答し、現在のリクエストに追加の認証が必要であることを示します。
  • 2行目:WWW-Authenticate認証チャレンジを実行します。
  • 2行目:PrivateTokenセッションで言及された新しい HTTP 認証方法です。
  • 2行目:issuerサーバーがトークンの発行を信頼するトークン発行者を示します。

このチャレンジには重要な制限があります。Web サイトで使用する場合、チャレンジはメイン Web サイト URL のサブドメインであるファーストパーティ ドメインから取得する必要があり、ページに埋め込まれたサードパーティ ドメインから取得することはできません (09:35)。

目隠し、機器の認証および発行

(05:58) クライアントはトークンが必要な場合、まず iCloud 認証者 (iCloud 認証サービス) に連絡します。クライアントはブラインド トークン リクエストを送信するため、iCloud 認証者はそれを元のサーバー チャレンジと関連付けることができません。

次に、iCloud 認証者はデバイスの Secure Enclave 内の証明書を使用してデバイスの認証を実行し、Apple ID のステータスを確認します。また、デバイスが通常の使用パターンと一致しているか、デバイス ファーミングに使用できるかを判断するためにレート制限を行うこともできます。

クライアントがチェックに合格すると、認証者はリクエストを発行者に渡します。発行者は iCloud 認証者を信頼しているため、トークンを発行します。発行者は顧客が誰であるかを知りません。署名を受信した後、クライアントはブラインド解除を実行し、検証のためにトークンを元のサーバーに返します。

Client -> Server: HTTP request
Server -> Client: PrivateToken challenge
Client -> iCloud Attester: blinded token request
Attester -> Issuer: validated token request
Issuer -> Client: signed blinded token
Client -> Server: unblinded signed token
Server: validate issuer signature

キーポイント:

  • 行 1: プロセスは通常の HTTP リクエストで始まります。
  • 行 2: サーバーは、追加の信頼信号がいつ必要かを決定します。
  • 3 行目: クライアントによって行われたリクエストは、サーバー チャレンジとの関連付けを避けるためにブラインド化されます。
  • 4 行目: 認証者はデバイス証明書に合格した後、リクエストを発行者に渡します。
  • 5 行目: 発行者は署名のみを担当し、ユーザー ID を受け取りません。
  • 6 行目: クライアントは、ブラインド解除された署名トークンをサーバーに渡します。
  • 7 行目: サーバーは署名が有効であることを検証しますが、トークンでクライアントを識別できません。

サーバーアクセスのための 3 つのステップ

(07:19) プライベート アクセス トークンへのサーバー アクセスには 3 つの手順があります。

まず、トークン発行者を選択します。発行者は、既存の CAPTCHA または不正行為対策サービス、Web ホスティング サービス、または CDN にすることができます。講演では、iOS 16 と macOS Ventura のベータ段階で、Fastly と Cloudflare がすでにテストできると述べられました。他の CAPTCHA プロバイダー、Web ホスティング サービス、CDN も後で発行者を実行できます (07:48)。

2 番目に、クライアントを認証する必要があるときに送信されます。PrivateTokenチャレンジ。既存の CAPTCHA または不正行為対策サービスにチャレンジをスクリプトに組み込むことも、独自のサーバーから直接送信することもできます (09:06)。

3 番目に、クライアントから返されたトークンを確認します。サーバーは発行者の公開キーを使用してトークンの有効性を確認し、リプレイ攻撃を処理する必要があります。Apple は、トークンは 1 回使用する必要があり、使用されたトークンを記録するか、トークンにチャレンジ内の一意の値に署名するよう要求することで、再実行を防ぐことができると明確に述べています (09:50)。

以下は、これら 3 つの決定ポイントを示す概念的なサーバー ロジックです。

async function handleRequest(request) {
  const token = request.headers.get("Authorization");

  if (!token) {
    return optionalPrivateTokenChallenge();
  }

  const valid = await issuerPublicKey.verify(token);
  const fresh = await replayStore.markIfUnused(token);

  if (valid && fresh) {
    return trustedClientResponse();
  }

  return legacyFraudCheckResponse();
}

キーポイント:

  • 1 行目: すべてのリクエストは最初に同じ処理入口に入ります。
  • 2 行目: サーバーは、クライアントから返された認証情報をリクエスト ヘッダーから読み取ります。
  • 行 4 ~ 6: トークンがない場合、メイン ページの読み込みをブロックすることなく、オプションのチャレンジを返します。
  • 8 行目: 発行者の公開鍵を使用して署名を検証します。
  • 9 行目: リプレイを防ぐためにトークンが使用されたかどうかを記録します。
  • 11 ~ 13 行目: トークンが有効で未使用の場合、リクエストをより信頼できるものとして扱います。
  • 15 行目: 検証失敗時に古い不正防止プロセスにフォールバックします。

ここで重要なのは、トークンをオプションの信頼シグナルとして扱い、古いクライアントが利用できるダウングレード パスを残すことです。古いクライアントはチャレンジに応答しないため、メイン ページの読み込みはそれに依存できません (10:23)。

アプリ側: URLSession と WebKit の自動処理

(10:39) Web サイトは、Safari および WebKit を介してサーバーにアクセスするときに、プライベート アクセス トークンを自動的に使用できます。アプリも直接メリットを得ることができます。

要件は 3 つあります。デバイスが iOS 16 または macOS Ventura を実行していること。デバイスは Apple ID を使用してログインしています。アプリが WebKit を使用しているか、URLSessionHTTP 経由でサーバーに接続します。Apple ID は構成証明にのみ使用され、トークンを受信するサーバーとは共有されません (10:49)。

URLSessionこれを処理する最も簡単な方法は、アプリが新しい API を明示的に呼び出す必要がないことです。フロントエンドアプリが受信するときPrivateTokenチャレンジに応じて、システムは認証応答としてトークンをサーバーに自動的に送り返します (11:25)。

let url = URL(string: "https://example.com/account")!
let (data, response) = try await URLSession.shared.data(from: url)

if let httpResponse = response as? HTTPURLResponse,
   httpResponse.statusCode == 401 {
    // Conceptual fallback: the token challenge was received,
    // but the system could not fetch a Private Access Token.
    showFallbackVerification()
}

キーポイント:

  • 行 1: アプリは独自のサーバーにアクセスします。
  • 2 行目: 使用するURLSessionHTTP リクエストを開始します。システムはサポートされているものを自動的に処理しますPrivateToken challenge。
  • 行 4 ~ 7: トークンの取得が失敗した場合、アプリはチャレンジを含む 401 応答を受信する可能性があります。
  • 8 行目: この時点で、ビジネスに適したダウングレード検証プロセスを開始する必要があります。

障害のシナリオには、アプリがフォアグラウンドにない、またはデバイスが Apple ID でログインしていないことが含まれます。401 を受信して​​も、プロトコルが使用できないことを意味するのではなく、アプリに独自のシナリオに基づいてダウングレードする方法を決定する機会が与えられます (11:41)。


重要ポイント

1. ログイン ページでの CAPTCHA の中断を減らす

  • 対処方法: ログイン プロセス中の優先認証方法としてプライベート アクセス トークンを使用します。
  • 実行する価値がある理由: セッションは、iOS 16 デバイスが従来の CAPTCHA をバイパスして直接ログインできることを示し、通常のユーザーの中断の回数を減らします。
  • 開始方法: Fastly、Cloudflare、または既存の不正行為対策サービスを発行者として選択し、ログイン インターフェイスでオプションを返しますPrivateTokenチャレンジし、失敗した場合は元の CAPTCHA を保持します。

2. 登録インターフェイスにワンタイム トークンを追加して、リプレイを防止します

  • 対処方法: アカウント登録インターフェイスの不正行為判定をトークン検証とリプレイ チェックの 2 つのステップに分割します。
  • 実行する価値がある理由: Apple は、トークンは 1 回限りの使用であり、サーバーはクライアントが同じトークンを繰り返し送信することを防ぐ必要があると明確に述べています。
  • 開始方法: チャレンジに一意の値を追加するか、使用したトークンをサーバーに保存します。検証に合格したらアカウントを作成します。

3. アプリ内 Web ログインのシステム機能の再利用

  • やるべきこと: WebKit のアプリに Web ページのログインまたはアカウント バインド プロセスを配置するか、次を使用します。URLSession独自の認証インターフェースにアクセスします。
  • 実行する価値がある理由: WebKit とURLSession自動で応答できるPrivateTokenチャレンジでは、アプリは手書きのトークン取得プロセスを必要としません。
  • 開始方法: リクエストがフォアグラウンドで発生することを確認します。既存の検証コードや手動検証エントリを表示するなど、401 応答をダウングレードします。

4. サードパーティの CAPTCHA スクリプトを段階的に置き換える

  • 何をすべきか: まず、プライベート アクセス トークンを、低リスク パス上の既存の CAPTCHA または不正行為対策プロバイダーに接続します。
  • 実行する価値がある理由: このスピーチでは、段階的な移行を促進するために、チャレンジを既存のプロバイダーによって自動的に統合できるか、サーバーによって直接発行できることが示唆されました。
  • 開始方法: ログイン後のアクション、レビュー送信またはトライアル登録ページを選択し、古い検証をすべてすぐに削除するのではなく、トークン検証結果をリスク スコアとして入力します。

関連セッション

コメント

GitHub Issues · utterances