Monappyのトラブルの原因を推測してみた

Monappyで不正出金事件が発生

一昨日の9月1日に、MonappyでMonacoinが不正に出金されるという事件が発生しました。

MonappyにおけるMonacoinの不正出金につきまして

ユーザ間で気軽に投げ銭ができるプラットフォームとして楽しく遊べるサイトだっただけに、悲しいです。

今後、他のサービスでも同様のトラブルが起こらないか心配です。
悪意のある人にとってはポピュラーな手口かもしれないので、再発防止のために詳細な流れが気になりました。
高負荷時に発生する事象とのことです。
自分の頭の整理のため、どういった流れで発生したのか推測してみました。

公式の説明文からの推測なので間違っている部分も多いと思います。
添削・ご指導いただけるとありがたいです。

原因の推測

気になったのは、公式発表の「攻撃の経緯」の「詳細」にある、以下の文です。

MonappyからMonacoinを送信する際は、monacoindという別のサーバ上のアプリケーションと通信する仕様になっています。この通信がタイムアウト等で失敗した場合はサーバダウンなどで送金に失敗しているとみなして、取引をロールバックする仕様となっていました。また、ギフトコードの処理に関してはデータベースのトランザクション機能等を利用しており、本来同じギフトコードを二重に使用することはできないようになっていました。しかし、高負荷状態でギフトコードを連続して使用しようとした場合、通信を受け取ったmonacoindの応答に時間がかかり、サイト側ではタイムアウトとなってロールバックされたあとにmonacoind側では送金が行われていました。この結果、一つのギフトコードから複数回送金されたものと考えられます。また、この攻撃に際し少額のMonacoinを大量に送付しておくことでcoind送信時の負荷を増大させようとする試みも確認しました。

Monappy上の残高を先に書き換えてmonacoindに送金処理を行うロジックになっていて、本来はmonacoindでの送金処理は即時に行われ、Monappy側に応答を返すはずが、monacoindが高負荷の場合は、下記の図のようにMonappy側がタイムアウトした後でmonacoindでの送金処理が行われたために、実際の残高とMonappy上の残高が食い違ってしまったというのが、推測です。

タイムアウトとタイミングの図

monappy-trouble (2).png

もしそうなら、どうすれば良かった?

対応としては、残高書き換えとmonacoindへの送金依頼の順番が逆(外部システムとのやり取りを先に行う)なら良かったのかと思いました。

余談:シーケンス図を描くツール

今回のシーケンス図ぽい図を描くのに、draw.ioを使いました。ユーザ登録なしで使えるのがいいですね。
しかし作成に小一時間かかってしまった上に、図が汚い。。。
何かいいツールをご存知の方いましたら教えてください m_()_m

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です