ユーザー識別や認可にメール要求を使用しないように移行を行う
この記事は、現在、認可にメール要求を使用するという安全ではないパターンを使用しているアプリケーションの開発者にガイダンスを提供することを目的としています。これは、別のユーザーによるアカウントの完全な乗っ取りを招くおそれがあります。 引き続きお読みになり、アプリケーションに影響があるかどうかについての詳細と修復の手順について確認してください。
アプリケーションに影響があるかどうかを確認する方法
Microsoft では、アプリケーションのソース コードを確認し、次のパターンが存在するかどうかを判断することをお勧めします。
email
などの変更可能な要求が、ユーザーを一意に識別する目的で使用されているemail
などの変更可能な要求が、ユーザーによるリソースへのアクセスを認可する目的で使用されている
これらのパターンは安全ではないと見なされます。プロビジョニングされたメールボックスを持たないユーザーは、メール (プライマリ SMTP) 属性に任意のメール アドレスを設定できるためです。 この属性は、検証済みのメール アドレスからのものとは限りません。 検証されていないドメイン所有者を持つメール要求を認可のために使用すると、プロビジョニングされたメールボックスを持たないユーザーが、Mail 属性を変更して別のユーザーに偽装することで、認可されていないアクセス権を取得する可能性があります。
次の場合、電子メールはドメイン所有者を確認済みと見なされます。
- ドメインはユーザー アカウントが存在するテナントに属しており、テナント管理者はドメインの検証を行った
- メールは Microsoft アカウント (MSA) からである
- メールは Google アカウントからである
- メールはワンタイム パスコード (OTP) フローを使用した認証に使用された
また、Facebook アカウントと SAML/WS-Fed アカウントには、検証済みドメインがないことに注意する必要があります。
この不正アクセスのリスクは、あるテナントのユーザーが Mail 属性を変更して別のテナントからリソースにアクセスする特権をエスカレートする可能性があった際に、マルチテナント アプリでのみ見つかっています。
アプリケーションをすぐに保護するための操作方法は?
未検証のメール アドレスという誤りからアプリケーションを保護するために、すべての新しいマルチテナント アプリケーションは、2023 年 6 月の時点で未検証のドメイン所有者を持つメール アドレスをトークンから削除するという新しい既定の動作に自動的にオプトインされます。 この動作は、以前にドメイン所有者の未検証のメール アドレスを使用したサインイン アクティビティがあったシングルテナント アプリケーションおよびマルチテナント アプリケーションでは有効になりません。
シナリオによっては、アプリケーションのトークンが未検証のメールを引き続き受け入れる必要があるとお客様が判断する場合があります。 ほとんどのアプリケーションではお勧めしませんが、Microsoft Graph でアプリケーション API の authenticationBehaviors オブジェクトの removeUnverifiedEmailClaim
プロパティを設定することで、既定の動作を無効にすることができます。
removeUnverifiedEmailClaim
を false
に設定することで、アプリケーションは検証されていない可能性がある email
クレームを受け取り、ユーザーを乗っ取りのリスクにさらすことになります。 ユーザー ログイン フローを壊さないようにこの動作を無効にしている場合は、次のガイダンスで説明するように、できるだけ早く一意に識別を行うトークン要求マッピングに移行することを強くお勧めします。
セキュリティで保護されていない構成の特定とデータベース移行の実行
認可チェックを実行したり、データベース内のユーザーにインデックスを付けたりするために、変更可能な要求 (email
や preferred_username
など) を識別子として使用しないでください。 これらの値は再利用できるため、アプリケーションを特権エスカレーション攻撃にさらすおそれがあります。
次の擬似コード サンプルは、ユーザーの識別/認可の安全でないパターンを示すのに役立ちます。
// Your relying party (RP) using the insecure email claim for user identification (or authorization)
MyRPUsesInsecurePattern()
{
// grab data for the user based on the email (or other mutable) attribute
data = GetUserData(token.email)
// Create new record if no data present (This is the anti-pattern!)
if (data == null)
{
data = WriteNewRecords(token.email)
}
insecureAccess = data.show // this is how an unverified user can escalate their privileges via an arbirarily set email
}
アプリケーションがこの安全でない属性に依存していることが分かったら、グローバル一意識別子 (GUID) 上でユーザーのインデックスを再付与するようにビジネス ロジックを更新する必要があります。
マルチテナント アプリケーションでは、一意に識別を行う 2 つの要求 (tid
+ oid
) というマッピング上でインデックスを付ける必要があります。 これは、tid
でテナントをセグメント化し、oid
でユーザーをセグメント化します。
メール検証の状態を確認し、ユーザーを移行するための xms_edov
オプション要求の使用
移行プロセスで開発者を支援するために、xms_edov
というオプション要求が導入されました。これはメールのドメイン所有者が検証済みかどうかを示すブール型プロパティです。
xms_edov
は、oid
などの一意の識別子に主キーを移行するまで、ユーザーのメールの検証を支援するために使用することができます。 次の擬似コードの例は、移行の一部としてこの要求をどのように使用できるかを示しています。
// Verify email and migrate users by performing lookups on tid+oid, email, and xms_edov claims
MyRPUsesSecurePattern()
{
// grab the data for a user based on the secure tid + oid mapping
data = GetUserData(token.tid + token.oid)
// address case where users are still indexed by email
if (data == null)
{
data = GetUserData(token.email)
// if still indexed by email, update user's key to GUID
if (data != null)
{
// check if email domain owner is verified
if (token.xms_edov == false)
{
yourEmailVerificationLogic()
}
// migrate primary key to unique identifier mapping (tid + oid)
data.UpdateKeyTo(token.tid + token.oid)
}
// new user, create new record with the correct (secure) key
data = WriteNewRecord(token.sub)
}
secureAccess = data.show
}
グローバルに一意のマッピングへの移行は、各ユーザーが基本的に、再利用したり別のユーザーを偽装するために悪用したりできない値でインデックスを付与されることを保証します。 ユーザーがグローバル一意識別子でインデックスを付与されるようになったら、email
要求を使用する可能性がある認可ロジックを修正する準備ができています。
適切な要求検証を使用して認可ロジックを更新する
アプリケーションが認可のために email
(またはその他の変更可能な要求) を使用する場合は、「要求の検証によるアプリケーションと API のセキュリティ保護」に目を通し、適切なチェックを実装する必要があります。
次の手順
- 要求ベースの認可を安全に使用する方法の詳細については、「要求を検証してアプリケーションと API をセキュリティで保護する」を参照してください
- オプション要求の詳細については、「オプション要求リファレンス」を参照してください