Edited at

ユーザー認証はクライアント側のパスワード保存に(100%ほど)依存すると潜める危険

More than 1 year has passed since last update.

この記事は個人の見解であり、所属する組織の公式見解ではありません。

辛い思い出ありますので言えますが、ユーザー認証はクライアント側のパスワード保存に依存してはいけません ^^; 通常認証に使わなくても、IDFVとかのバックアップ用端末->アカウント紐付き情報を取ってね。

数千人、数万人のクライアント側パスワード情報がバグによって同時に消えることありますので^^

ゲーム滅亡を避けましょう^^


実際にあった話

うちのチームのローンチ時に起きました。

数千人のクライアント側パスワード情報が同時に消されました。

IDFV情報を持っていたおかげでユーザーログインに影響なかったですが、その情報がなかったら数千人がCSに連絡するor二度とプレイできません。ゲームの規模がより大きくて数万人、数十万人の被害者が出た場合、地獄を想像します ^^;


滅亡の作り方


名前/PWがないとユーザー認証できない仕組み

クライアント端末とサーバーアカウントを紐づけるのは、クライアント側のキーチェインに保存するユーザー名とパスワード。のみ。IDFVとははサーバーが保存しません。

//サーバー側のユーザー情報でPWを保存しますが、IDFVとかを保存しません

CREATE TABLE `USER_INFO` (
`USER_ID` varchar(32) NOT NULL COMMENT 'ユーザーID',
`PASSWORD` varchar(32) NOT NULL COMMENT 'パスワード',
//...
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='ユーザー情報';


クライアント側名前/PWリセットロジック

クライアント側に「ユーザー情報がサーバーにない場合、クライアント側ユーザー名とパスワード情報をリセット(==削除)する」ロジックを置きます。

こんなロジックは珍しくないです - 開発環境等でたまたまDBがリセットされていますので、デザイナーとテスターから「簡単にクライアントをリセットさせて」の要望がよく来ます。

//ログインAPIを叩いてみる

error_message = login_to_server();
//サーバーにユーザーが存在しない場合...
if(error_message == USER_NOT_FOUND) {
delete_password_from_keychain(); //...認証用名前/PWを削除
}


サーバー側バグ(一つ)

負荷とかによってサーバーがDBに繋がれない時、例外とかじゃなくてUSER_NOT_FOUNDレスポンスを返します。

//ユーザーIDからユーザー情報を取得

try {
$user = get_user_info($user_id);
} catch (Exception $e) { //<-- バグはここ - 例外種類を確認ぜす、どんな例外でもUSER_NOT_FOUNDを返す
return new Response(USER_NOT_FOUND);
}


滅亡への流れ


  1. 本番が公開されて、最初の日から人気


  2. 人気なので、負荷でDBが落ちてしまう


  3. DBが落ちたせいで、ログインAPIはUSER_NOT_FOUNDレスポンスを返す


  4. クライアント側がユーザーの名前とパスワードを削除する


  5. 数分に数千、数万人がログインAPIを叩いてパスワードをなくす


  6. 滅亡



「実際の話」は他のゲームでも意外と起きられる理由

「実際の話」系現象は、うちと関係ないチームでもまた起きたらしいです - 間違いなくバグですが、初心者チームで負荷時レスポンスは確認されない時が多いです(別な話ですが、負荷テストが大事!)

なお、「実際の話」より恐ろしいなのは、上記以外のバグもpw削除を呼び起こせます。クライアント側ロジックミス、pw上書きなど。特定なシチュエーションで潜んだバグが動き始める場合、同時に数万人のpwが消える結果は同じです。


対策

こちらの対策として、端末に保存するもの以外の緊急紐付きを用意する - IDFVとか、Facebookアカウントとか。

IDFVも100%信頼できません。どんなIDでも、事情によって問題が起きるかもしれません(数年前の例ですがいきなりAppleがAdvertising IDの利用を禁止にしました - 間違って認証内でAdvertising IDを使っていたゲームはいきなり申請通らなくなりました)。ですが、重要なのは、IDFVとキーチェインデータの両方が同時に使えなくなる可能性はかなり低いです。(と信じたい ^^; ) 問題があったら、どれかから復活でるはずです。(と信じたい ^^; )

あと、まあ負荷テストは大事ですね^^