ポケモンで学ぶRDB用語とセキュリティ 2
※本シリーズはフィクションであり、現実の実装とはなんら関係ありません。また間違いはいつでもご報告いただけますと幸いです。
さて、ポケモンという「もの」をインターネットで送る、あるいは送られるためにはwebの設定が必要である。このときに問題になるのは様々あるが、ここでは2つ取り上げよう。セッション管理とバグポケ (改造ポケモン) である。
セッション管理
ポケモン交換や配布においていちばん重要なのは多分これではないだろうか。セッション管理ができていないと「まだおくりもの受け取っていないのにもう受け取った扱いになっている」「相手のポケモンは届いてないのに自分のポケモンだけ行っちゃった」という泣くしかない構図が出来上がる。実はSVのDLCおくりものヒスイゾロアークの際にはこれが起こってしまったようであり、天下のポケモンが... とびっくりした覚えがある (もちろん推察なのでセッション管理以外の問題かもしれない)。自分の通信環境やバッテリーのせいならばぎりぎり自己責任とも言えなくもないが、サーバの混み合いのせいでこれはかわいそうである...
話がずれた。セッションとは通常一体として行われるべき複数ジョブのひとかたまりであり、1つのセッションは完了した状態かまったく始まっていない状態の2値を取ることが求められる。例えばふしぎなおくりものならば
1. ユーザがレポート後に通信を確立し、あいことば (パスワード) を送る。
2. サーバがパスワードを検証し、該当するポケモンなりわざマシンを送り返す。
3. 同一ユーザからの同一パスワードを拒否するよう設定する。
4. ユーザのローカル環境に変更が反映され、レポートされる。
のざっくり4ジョブが1セッションである。もちろんこれ以外をジョブにしたりセッション区切りを変更する可能性もあるが、少なくとも2〜4は1セッションになる必要がある。理由は上のヒスイゾロアークの例が物語っている。パスワードを送り、3まで行って4が完了していない段階で異常終了すると、ヒスイゾロアークがユーザのローカル、つまりボックスに存在しないまま3のロックがかかり、二度とヒスイゾロアークを受け取れなくなってしまうのである。
もっと万全を期すなら1を受信するサーバAと2、3を管理するサーバBは別立てにし、確実にセッション管理ができる帯域状況であるとAが判断してからAからBにユーザを繋ぎ変え、2〜4をセッションとして実行したほうが良さげである。しらんけど。
ユーザ同士の通信交換の際も同様である。
バグポケ
正規プレイヤーを悩ませるバグポケ。私はどうやら受け取ったことがないようだが、中古ロム開封を見ると出るわ出るわ、まぁ正規の方法で行った (?) 謎の場所シェイミくらいはギリ許容するにしても、どっから湧いたんやというような出自のポケモンが色違いや証のために生成されているのが現状である。
ローカルで楽しまれる分には生暖かい目で見ていられるのだが、これを交換に流すやつがいる。特にマジカル交換という良くも悪くも後腐れない方法で流されるという話はよく耳にする。これを防ぐ方法を考えよう。
これは伝説・幻ポケモンほど楽に対策できる。なぜなら特に彼らの色違いはいつどこでどのように配布・入手されたのかがほぼわかっており (ブロックルーチンがかかっていることが多い)、そいつのハッシュ化キー (昨日の議論参照) をデータベース化・計算すれば良いからである。
例えばダークライの色違いならば、メンバーズカードからの固定シンボルリセットしかないから、捕獲ユーザーのIDと捕獲日時から、色違いだろうがなんだろうがダークライのハッシュ値は一意に定まる。サーバ内で交換に出されたダークライっぽいデータの捕獲者IDと捕獲日時から予定されるハッシュ値を計算し、ハッシュ値が合わなければ (あるいは明らかに出現しない場所での捕獲ならば) 弾けば良い。
ここでもハッシュ値の衝突発見困難性が役に立つ。種族を縛られた状態で捕獲ユーザIDと捕獲日時とタイムゾーンをハッシュ値が整合するように生成するのは、いくら任意コード実行とはいえ難しいのではないだろうか。さらに一意ハッシュ化の方法が知らされていなければおそらく不可能と言って良い。
これがバグポケを防ぐ一種のファイアウォール構築である。なおA0改造などの場合、多少ハッシュ化を工夫する必要が出てくる。
改造はローカルだけにしようね!
明日に続くかは未定だけど色々勉強になるので続けたい...?