12/9更新:不具合の原因となったコード(再現)と、レトロPC経験者向けの補足コンテンツを追加しました。
今回のポイント
- テストアカウントは一目で分かる偽名にする(本名にしない)
- メソッドの先頭にバリデーション処理を入れる
- あらかじめ動作テストしてバグを解決する
自己紹介を読みたい方はこちら
論破しない・ひろゆき(本名:大和 広幸)
都内中小企業のITコンサルタント兼社内SEを担当、
WEBフルスタック歴8年以上。
小学生の頃にBASICを知り、ホームページや
WEBアプリ制作などを経て現在に至る。
近年はカルト宗教二世経験をもとに
心理セラピーや児童保護支援にも取り組んでいる。
なぜ私の本名が晒されてしまったのか、その経緯について
数年前、ある顧客向けサービスを運用していたときの話。
そのシステムは新型コロナの影響でサービス提供できず、
コスト削減するため既にサービス終了している。
不具合が出た当時、私はシステム運用担当だった。
※フロントエンド担当、テストサーバからの手動デプロイ
※メイン開発担当者は別にいた(以後F氏とする)
ある日のこと。
「(一般ユーザーが)ログインした後の『ようこそ○○さん』に、
お前の本名が表示されているぞ!
全てのユーザーがそうなってる可能性あるから、すぐ調べてくれ」
という報告が顧客サポートからあった。
なぜ私の本名が!?
そのバグ発生後しばらくの間、流出した私の本名とともに
togetterなどで不具合を指摘されることになった。
もちろん顧客情報の流出疑惑と、その釈明に追われることになった。
(スクリーンショットを取るためネット検索したが見つからず)
発生当時は事態の重さをあまり感じなかったが、
炎上してからその重さが心にのしかかってきた。
さらに幼少期のトラウマが再発し
「私の名前がよくなかったのか?」と悩むように。(余談参照)
ちなみに、かつて在籍していた会社はシステム以外にも
ひんぱんに炎上と火消しを繰り返している会社だった。
ゆえに在籍中なら語ることができなかった。
もし語ろうものなら顧客から「やっぱり貴様か!」と言われかねない。
いまは既に退社しているので、
そろそろ語っても誰も文句は言ってこないはず。
:
と信じたい。
不具合の原因は?
原因はMySQLのユーザーテーブルを見て想像がついた。
「これはメールアドレス値の渡し忘れではないか?」と。
システムはPHPフレームワークで作られており、
実際に処理メソッドを調べたらそのとおりだった。
// 当時の不具合内容に近いコードを再現
protected function getUserData($mail_address) {
$result_1 = $this->users->where("first_mail", $mail_address);
if ($result_1->count())
return $result_1->fetch();
$result_2 = $this->users->where("second_mail", $mail_address);
if ($result_2->count())
return $result_2->fetch();
return [];
}
そのことをF氏と上長に報告。
そのあと了承を得て、不具合箇所を修正。
// 当時、不具合対処したときの内容に近いコードを再現
protected function getUserData($mail_address) { // after
if (empty($mail_address)) return [];
$result = $this->users->where(
"(first_mail = ? OR second_mail = ?)",
[$mail_address, $mail_address]
);
if ($result->count())
return $result->fetch();
return [];
}
個人情報についても実際の顧客情報は
漏洩していないことを釈明して火消しに至った。
ではなぜそれを思いついたかというと、
中学校くらいの頃、別のプログラミングで
似たような事象に苦しんだことがあるから。
1980年代中期の某PCでプログラミングする際、関数のリターンに相当する命令(RET)を指定し忘れたりするとフロッピーディスクが論理破壊される事象があった
補足:Z80やMSXが分かる方向けの追加解説
この事象が発生したPCは「FS-A1F」という機種名で、キーボードとFDD一体型のMSX2規格のPCでした。
使える言語は処理速度の遅いBASICと、処理速度が速いZ80CPUネイティブコード(通称マシン語)の2種類ありました。
なぜフロッピーディスクに影響が出たか。この機種のメインメモリ配置とBASICからマシン語を実行する際の不注意によります。
メモリ配置イメージ:[BASIC領域][ユーザー領域][フロッピーディスク関連領域]
さらに私は当時ハンドアセンブル、すなわち紙にマシン語を書いてからプログラミングしていました。
その際プログラムポインタ関連命令(RET、JP、JRなど)の設計ミスで、不本意にフロッピーディスク関連領域にアクセスすることが何度もありました。
おそらくその時のユーザー領域は以下のようになっていたと思われます。
メモリ配置イメージ:[BASIC領域][自作プログラム][00(NOP)による空領域][フロッピーディスク関連領域]
マシン語のバグで予期しないフロッピーディスクランプが点灯し、再起動後にBASIC上でFILESを実行すると「Disk I/O Error」が出て泣く泣くフォーマットを迫られた原因は、上記のようなメモリ配置だったのではないかと想像しています。
これをわかりやすい別の表現でいうなら、
「階段に足をのせたら下のフロアまですべり落ち、さらに上から金ダライが落ちてくる」コントの仕掛けになっている
システム運用において、
まさかドリフのコント的な罠にはまるなんて思ってもなかった。
そこから学んだことや、対処方法は?
1、テストアカウントは一目で分かる偽名にする(本名にしない)
用紙記入例やフォームのプレースホルダで
このような設定を見かけませんか?
性「○○」(会社名などの一部)
名「太郎」
性カナ「ナントカ」
名カナ「タロウ」
これだとパッと見わかりづらいので、私の場合は
性「手素戸」
名「赤運斗」
性カナ「テスト」
名カナ「アカウント」
このようにしています。
他のメンバーから 「テストユーザーにヤンキーがいる」
と言われますが、分かりやすさを重視するためです。
ちなみに、テストアカウントをおしゃれにしようと
暗黙の匿名と言われている名前「アラン・スミシー」を設定したら
当時のWEB担当から「実在するのでやめてほしい」と言われました。
性「阿藍」
名「隅史」
性カナ「アラン」
名カナ「スミシー」
その経緯もあって、
テストアカウントはヤンキー上等で今に至ります。
2、メソッドの先頭にバリデーション処理を入れる
今回の場合、メールアドレスなど
DB探索に必要な情報が空だった場合は
空配列を返し、予期しない動作を防ぐ方法もあります。
私はこれを「門前払い」と呼んでいます。
3、あらかじめ動作テストしてバグを解決する
プロジェクト体制がしっかりしているなら
開発段階でテストして検出・解決できた問題とも考えられます。
ひとり情シスや社内SEは誰かにテストしてもらうか、がんばれ![]()
余談・アカウント周りのシステム不具合は影響大
技術的な影響範囲以上の問題になりかねないです。
1、個人情報の流出・漏洩が疑われる。
その調査や第三者への謝罪など、会社に大きな負担がかかるため。
2、本名が晒された当事者にとって、別の問題にも発展しかねない
その会社のサービスを利用していることが公表されることで、
家族や親戚から「お前はそんなことをやっているのか!」
とも言われかねません。
わかりやすく例えるなら、本名が晒されることで
「Dなんとかのエロコンテンツサービスに課金してて、
しかも○○の性癖がある」(○○は、ご想像におまかせします)
とか他人にバレたらどう思いますか?なんか嫌ですよね。
(補足:私の幼少期トラウマ経験について)
私はもともと名前にコンプレックスを持っていました。
この不具合事象があってから、
「この名前で慈善活動するなら許されるのだろうけど
仕事やお金もうけをやってはいけないんだろうか」
と悩みつづける原因になりました。
このことについては今年進展があり、
メンターの1人から向き合うようアドバイスをいただきました。
命名の意図について親に手紙で確認することにしました。
その結果、私の名前に博愛主義的な意図はなかったことが判明しました。
最後に
今ふりかえると、システムも幼少期のトラウマも
1つ1つアップデートすることが大事だと私は思います。

