職業柄見つけてしまったバグのお話

職業柄、仕事でないのに市販のものが何か気になる、何かしたくなるってことありますよね。
皆様は職業柄どんなことが気になりますか、そしてしたくなりますか?

そんな自分はシステムエンジニア(SE)。
SEという職業柄、市販のシステムでバグを見つけると報告したくなるんですよ。
そんなこと言いつつも、市販のシステムは検証を済ませ、それなりの期間が経過しているものが多いので、よほどのことがない限りバグを見つけることはありません。

しかし、1月になって2件のシステムでそれぞれ1件のバグを見つけてしまいました。
せっかくなので、それら不具合について書き残したいと思います。


◎某コンビニのID登録システム画面表示不具合
某コンビニではメールアドレスがIDとなっており、ID登録をする際にメールアドレスによる認証をしています。
メールアドレスの存在確認をする仕組みは一般的ですが、メール送信後の画面で軽微な不具合を見つけました。
メール送信完了画面に表示されたメールアドレスを見ると、半角プラス記号(+)が半角スペース( )で表示されてました。

Gmailで公開されたことで認知度が高まってきておりますが、メールアドレスのアカウント名と@の間に「+」を入れ、その後任意の文字列を指定することで、複数のメールアドレスのように見せつつ同じメールアドレスで受信できるメールエイリアス機能があります。「+」を許容するメールシステムはそれほど多くないものの、メールアドレス漏洩対策の一環として「+」を含めたメールアドレスを許容しているメールシステムには「+」を含めてメールアドレスを登録しています。

例えば、メールアドレスが「nekodaisuki@example.com」だとし、コンビニ登録用として使用する場合、「nekodaisuki+konbini@example.com」をメールアドレスの情報として利用しても、そのアドレスに送信されたメールが「nekodaisuki@example.com」に届くのですね。
しかし、そのコンビニのシステムではメール送信完了画面で「nekodaisuki+konbini@example.com」ではなく「nekodaisuki konbini@example.com」と表示されてました。

「+」がスペースになる原因はすぐに推測できた訳ですよ。
HTTPリクエストで送信されたURLエンコーディング処理をそのまま利用し、本来なら「+」をそのまま「+」と表示しなければいけない処理にしていないなと。

問合せシステムで連絡したところ、案の定そのような回答でした。
メール送信機能自体には不具合はなく、メール送信完了画面の表示不具合については近日中に改修を行うとのことでした。

・教訓
世の中で使用されているメールアドレスはRFCに記載されている通りであると思ってはいけない。
Webシステムの場合、URLエンコーディングで置換対象となる文字列は復号された場合にも問題がないか意識すること。


◎某航空会社メールアドレス変更不具合
「某」って書いてもこちらはほぼ推測されそうだわΣ

事の発端は昨年11月頃にメールアドレスを変更したことになります。
今月の誕生日に某航空会社からお誕生日おめでとうございますメールが届いたのですが、変更後のメールアドレスではなく、変更前のメールアドレスに届きました。

会員ページを見たところ、メールアドレスは変更されており、昨年のメールアドレス変更後からお誕生日おめでとうございますメールが届くまでの間に旧メールアドレスに届いたものはありませんでした。

こちらも問合せシステムで問合せましたが、変更前メールアドレスに送信した履歴が残ってないとの回答でしたΣ
そのメールを送って欲しいと言われたので、お誕生日おめでとうございますメールをメールヘッダ付きで提供しました。

気になったのが、こちらも「+」を含むメールエイリアスのメールアドレスを使用して登録していることでしょうか。
その航空会社サイトでは、RFCに合わせているのかメールアドレスに使用できる文字は半角の英数字、「@」、「-」、「_」、「.」のみと記載されてました。
しかし、メールアドレス入力画面で「+」を含むメールアドレスを入力すると登録できてしまうんですよ。その後、メールアドレス変更完了メールも届いているので、アドレス変更自体も成功してるはずなんですよね。

そんなことを考えつつ、返信を待っていたところ、とうとう回答が届きました。
原因は、メール配信システムの不具合で、昨年のお誕生日おめでとうございますメールに配信した一部の情報が残っていて、変更前のメールアドレスに配信されてたとのことでした。

詳しい仕様の回答がありませんが、今回の仕組みと原因は以下だと推測しました。

・最新顧客DBからその都度最新情報を抽出する仕組みにしない理由
航空会社レベルの会員数になると2000万人を超えている為、DBからある日が誕生日の人の情報を取得するだけでも数万名の情報を取得することになる。
その為、お誕生日おめでとうございますメールは、最新の顧客DBから対象日に一致する利用者の氏名とメールアドレスを抽出し、メール配信システムへ登録する日次処理にはできない。

・推測したシステム全体の仕組み
重たい処理にしない為には、顧客情報の各レコードにタイムスタンプの項目を用意し、レコード最終更新日時を格納できるようにする。
利用者に公開しているオンラインシステムでは、利用者が情報を変更すると、タイムスタンプの項目を操作した日時にした情報レコードを挿入する仕様とする。
他システムに連動する情報の登録・修正・削除は、タイムスタンプの最終更新日時が数日以内のレコードを対象にする。

・推測したメール配信システムの仕組み
メール配信システムは月日別に宛先情報(顧客名とメールアドレス)を格納している。
日次処理バッチが起動することにより、顧客DBから最終更新日時が数日以内のレコードを抽出し、宛先情報の登録・修正・削除の処理を進める。
宛先情報の登録、修正、削除はメール配信システムに格納している情報と、顧客DBから抽出した情報の比較により判断する。

・今回の事象が発生した原因
メール配信システムへの情報変更処理が、何らかの不具合により実行されず、古いメールアドレスのまま情報が残っていた。
RFCを満たさないメールアドレスの変更とメール配信停止を同じ日に実行したことが原因?

・教訓
メール配信システム、更に言えばSMTPログのレベルでメール配信の成功・失敗を確認できる仕組みが必要。
処理の都合上、最新DBから最新情報を取得する仕組みにできない場合、情報を追加・修正・削除するタイミングで、情報の不整合が発生しないかの観点で検証パターンを作成する。
特に削除フラグや抑止フラグにより処理の中止や削除が発生するパターンに気をつける。
顧客メールアドレスのRFC準拠は事実上無理なので、諦める。
猫は可愛い。


そんなわけで利用者にバグを見つけられると、中の人は報告書の作成やらで大変なことになっているだろうと思いつつ、この話を終わらせたいと思います( ̄∇ ̄)ノ♪