2014年7月7日月曜日

JSON SQL Injection、PHPならJSONなしでもできるよ

DeNAの奥さんと、はるぷさんがJSON SQL Injectionについて公表されています。
上記の記事は、主にPerlスクリプトがJSONデータを受け取るシナリオで説明されています。もちろん、この組み合わせに限定したはなしではないわけで、それではPHPではどうだろうと思い調べてみました。

JSON SQL Injectionとは

以下、はるぷさんの「不正なJSONデータによる…」にしたがってJSON SQL Injectionについて説明します。
Perl向けのSQLジェネレータの一つであるSQL::Makerにおいて、以下のスクリプトを想定します。
my ($sql, @bind) = $builder->select(
    "table_name", ["*"],
    {"name"=>$user_name});
ここで、$user_nameとして 'yamada' を与えると、以下のSQL文が生成されます。
SQL文: SELECT * FROM `table_name` WHERE (`name` = ?)
変数: yamada
$user_nameが外部からJSON形式で渡ってくる場合(APIなどのように)を想定すると、ここの部分のJSONデータが {"key":"value"} となっていると、SQL::Makerは、keyをWHERE句の比較演算子とみなし、以下のSQL文を生成します。
SQL文: SELECT * FROM `table_name` WHERE (`name` KEY ?)
変数: value
ここで、keyの部分は任意の文字列を書くことができ、それが *そのまま* SQL文に流し込まれます。この仕様を悪用すると、SQL文を本来意図しない形に改変できてしまいます。これがJSON SQL Injectionです。


PHPではどうか?

それでは、我らがPHPではどうでしょうか。
@memememomoさんがSQL::MakerをPHPに移植されておられまして(参照)、これを使うと、JSON SQL Injectionが再現できます。
$builder = new SQL_Maker(array('driver' => 'mysql'));
list($sql, $binds) = $builder->select('table_name', array('*'), array('name' => $user_name));
ここで、$user_nameが'yamada'の場合、以下のようにPerl版とまったく同じ結果になります。
SQL文: SELECT * FROM `table_name` WHERE (`name` = ?)
変数: yamada
次に、$user_name = array('key' => 'value'); とすると、生成されるSQL文は下記のとおりです。
SELECT * FROM `table_name` WHERE (`name` key ?)
すなわち、JSONのキーとして指定した値が *そのまま* SQL文に注入されます。JSON SQL InjectionがPHPでも再現出来ました。
ここでは、PHP版のSQL::Makerを題材として使用させていただきましたが、後述するように、他にも同様の挙動をしめすSQLジェネレータを確認しています。

PHPの場合はJSONは必要ない

しかし、上記のスクリプトにおいて、SQLインジェクションを起こすためには、入力値がJSON形式である必要はありません。$user_nameが連想配列(文字列をキーとした配列)であれば良いわけですので、PHPの場合であれば、以下のようにHTMLフォームからでも指定は可能です。
先のスクリプトで、$user_name = $_GET['user_name'] としていた場合、以下のクエリ文字列でスクリプトを呼び出すと…
http://example.jp/query.php?user_name[key]=value
生成されるSQL文は下記となります。
SELECT * FROM `table_name` WHERE (`name` key ?)
このため、keyの箇所に任意のSQL断片を指定することにより、SQLインジェクション攻撃が可能となることを確認いたしました。一例を挙げます。
http://example.jp/query.php?user_name[>''+or+1%3d1)%23]=value
生成されるSQL文は下記となります。
SELECT * FROM `table_name` WHERE (`name` >'' or 1=1)# ?)
PHPの場合、JSONを使わなくてもJSON SQL Injectionができてしまう(*1)ことになり、該当するSQLジェネレータを使っている場合、広範囲のアプリケーションが脆弱になる可能性があります。

*1: この場合、JSON SQL Injectionという呼称は適切でないと考えられます。

対策

PHP版のSQL::Makerについては、対策版が公開されています。本家Perl版と同様に、strictモードが導入されました。memememomoさん、対応ありがとうございます。
これは以下のように使用します。
$builder = new SQL_Maker(array('driver' => 'mysql', 'strict' => 1));
$user_name = array('key' => 'value');
list($sql, $binds) = $builder->select('table_name', array('*'), array('name' => $user_name));
この際の実行結果は下記のように例外が発生します。
PHP Fatal error:  Uncaught exception 'Exception' with message 'cannot pass in a ref as argument in strict mode' in /home/ockeghem/php-SQL-Maker-master/lib/SQL/Maker/Condition.php:52
strictモードが使えない場合は、条件設定に与える引数の型チェックを行う方法があります。
  $user_name = $_GET['user_name'];
  if (! is_string($user_name)) {
    # エラー処理
    exit;
  }

他のSQLジェネレータの状況

SQL::AbstractのPHPへの移植版についても同種の問題があることが分かっています。作者に連絡をとったところ、古く個人的なプロジェクトであり、かつ開発者自身の使い方では strict モードに移行すると過去のスクリプトが動かなくなると言うことで、strictモードの対応は今のところないということでした。元々、ライブラリ側の脆弱性とまでは言えない問題ですので、これは仕方ないと考えます。呼び出し側での対応をするのがよいでしょう。

FluentPDOの場合、任意のSQL断片を注入することはできないようですが、パラメータとして配列を与えることによって、等号ではなく IN 演算子を使うものに変更はできるようです。以下のスクリプトで説明します。
$pdo = new PDO("mysql:dbname=...
$fpdo = new FluentPDO($pdo);  // FluentPDOオブジェクトの生成
$query = $fpdo->from('user')->where('id', $_GET['id']);
まず通常のケースとして、クエリ文字列を ?id=yamada とすると、生成されるSQL文は以下となります。yamadaはバインドする値として指定されます。
SELECT user.* FROM user WHERE id = ?
次に、?id[]=yamada&id[]=sato とすると、生成されるSQL文は以下の通りです。
SELECT user.* FROM user WHERE id IN ('yamada', 'sato')
これにより、特定IDの存在の有無を確認するようなケースでは、一度に多数の候補を試すことができることから、少ないリクエストでの探索が可能になります。


まとめ

SQLジェネレータが生成するSQL文について、PHPを使う場合は、JSONを用いていない場合でも、JSON SQL Injectionと類似の問題が発生する可能性があることを紹介しました。ライブラリの特性・仕様を理解した上で、正しい使い方により、脆弱性の混入を防ぎましょう。

また、私1人の調査には限界がありますので、類似の問題を見つけた方は教えて頂けると幸いです。

2014年4月30日水曜日

三井住友VISAカードのフィッシングサイト

昨日当方に来た以下のメール。メール自体はやる気のないフィッシングという感じでしたので、中身を見てやろうと検証環境を起動しました。閲覧しただけでマルウェアに感染するかもしれませんので…


で表示されたのは、1回リダイレクトして、以下のサイト。デザインが本物そっくり(同じ?)なのは当然として、アドレスバーに注目ください。



ちなみに、本物はこれです。


URLを見ると、

本物: https://www.smbc-card.com/vp/create/create_user.do
偽物: http://www.smbc-card.com.xxxxxx.com/vp/create/create_user.html

ということで、違いは下記の通りです。
  • 本物はEV SSLだが、偽物はHTTP(HTTPSですらない)
  • ドメイン名は、偽物は先頭は同じだが、後ろに xxxxxx.com がついている
  • 拡張子の違い(.do と .html)
筋論から言うと、ドメイン名の見分け方を学習してもらうべきところではありますが、一般の方に理解いただくのは中々難しそうです。ということで、
  • そもそもメールに書いてあるURLは閲覧しない
  • 銀行やクレジットカードのサイトは EV SSL の企業名・組織名を確認する
というあたりが対策としてよいのではないでしょうか。

ところで、twitter上では、メールの電子署名で確認できないかというコメントを頂きました。これは筋としてはよいと思うのですが…
たまたまSMBC VISAからの本物(と思われる)メールが来ていますが、本物にもS/MIME署名はありませんでした。同じSMBCでも、銀行の方はS/MIME署名がされています。

ということで、皆様もお気をつけ下さい。

PS.
拡張子の .do が時節柄気になるところではありますね。

2014年4月11日金曜日

PHP考古学: PHP4.2.xではmb_eregは複数行モードで動作していた

大垣さんのブログエントリに刺激を得て、古いmb_eregの挙動を調査しました。その結果、 PHP4.2.x上のmb_eregは複数行モードで動作していたことが分かりましたので報告します。

前回までのまとめ

正規表現によるバリデーションでは ^ と $ ではなく \A と \z を使おう」にて、Ruby、Perl、PHPの正規表現では、^ と $ は、「行」の先頭と末尾を示していて、文字列の先頭と末尾を指定するには、\A と \z を使うべきであることを説明しました。そして、Rubyの場合はデフォルトが複数行モードであるので、^○○○$ という形で全体一致検索を指定したつもりでも、簡単にチェックをすり抜け重大な脆弱性に直結します。一方、PerlやPHPの正規表現はデフォルトでは単一行モードであるので、文字列末尾の改行をチェックできないという問題はあるものの、重大な脆弱性に直結するケースはあまりないと考えられることを指摘しました。

古いバージョンのmb_eregはデフォルトが複数行モードだった?

ところが昨日大垣さんの書かれたエントリ「なぜRubyと違い、PHPの正規表現で^$の利用は致命的な問題ではないのか?」には以下のように書かれていました。
実は古いmbregex(忘れるくらい古い4.xの時代の話です)はRubyと全く同じ動作をしていました。この動作はセキュリティ上の問題であるとして、現在の^は\A(データの先頭)と同じ、$は\Z(改行を含む終端にマッチ)に変更されました。
私がPHPに親しむようになったのはPHP5.2以降のことなので、「忘れるくらい古い4.xの時代の話」は知らないのですが、どうしても知りたいと思い調べてみました。
といっても、私の手元にはphpallにて PHP4.4.9とPHP5.0.0以降のバイナリはすべてありますが、それより古いPHPはありません。そこで、この機会に、すべてのPHP4もビルドすることを決意いたしました。phpall完全版とでも言いましょうかw

phall完全版

phpall完全版と言っても、ここからPHPの古いソースをダウンロードしてビルドするだけです。@hnwさんが指摘するように、PHP5の古いバージョンをビルドするのはコツがいります。
実は、PHP 5.0.0-5.0.3はgcc4 でコンパイルできないという問題点があります。gcc4でコンパイルするためには、http://bugs.php.net/bug.php?id=32150 の通り、Zend/zend_modules.h を修正する必要があります。
こんなときgcc3でコンパイルするのも一つの手ですが、MacOSX10.4や10.5ではgcc3が提供されていません。今後このような環境が増えてくるのではないでしょうか。
また、PHP 5.2.0-5.2.3は./configureの途中で下記のように怒られてしまいます。
configure: error: installation or configuration problem: C++ compiler cannot create executables.
原因は追いかけていませんが、autoconfでconfigureスクリプトを作り直すと問題なくバイナリのビルドまで通ります。
phpallコマンドでPHPの全バージョンの挙動を試すより引用
後者のPHP 5.2.0-5.2.3の問題については、独自の調査により新たな知見を得ております。お恥ずかしいことに実験ノートをきちんとつけていなかったので、いつ・どのように発見したかを示す証拠はないのですが、以下のようにg++を導入することにより、エラーなくビルドできるようになります(Ubuntu 12.04LTSにて確認)。
$ sudo apt-get install g++
この方法で、私はこれまでに200回2回ほどPHP5.2.0-5.2.3のビルドに成功しています。まぁ、C++コンパイラが動かないよというメッセージに素直に従っただけということですがw
PHP4については、gccのバージョンが上がりチェックが厳しくなったためにエラーになる箇所が複数ありました。具体的には、static変数をextern宣言している等です。これらは、ソースの方を修正しました。
先のアーカイブにはPHP3.0.18のソースもあったので、ついでにこれもビルドしました。ということで、PHP3.0.18、PHP4全て、PHP5全てを含む「phpall完全版」の誕生です。

試してみる

以下のソースで試してみました。
<?php
  $a = "abc\n123\ndef";
  var_dump(mb_ereg('^[0-9]+$', $a));
実行結果は下記となります。mb_eregが実装されたのはPHP 4.2.0以降なので、該当バージョンのみ示します。
$ phpall mbereg.php
php-4.2.0: int(1)
php-4.2.1: int(1)
php-4.2.2: int(1)
php-4.2.3: int(1)
php-4.3.0: bool(false)
php-4.3.1: bool(false)
php-4.3.2: bool(false)
...
php-4.3.11: bool(false)
php-4.4.0: bool(false)
...
php-4.4.9: bool(false)
php-5.0.0: bool(false)
...
php-5.5.11: bool(false)
php-5.6.0beta1: bool(false)
なんということでしょう! PHP 4.2.xでは、大垣さんの指摘のように、mb_eregが複数行モードで動いていたようです。
PHP 4.3.0でこの仕様は単一行モードに変更されていますが、その理由は、大垣さんの言われる「セキュリティ上の問題」というよりは、eregと仕様を合わせたということではないでしょうか。mb_eregはeregからの移行を想定していると思われますし、mbstring.func_overload = 4 とすると、ereg関数の呼び出しがmb_eregにオーバーロードされるわけで、eregとの互換性は重要です。

この問題による影響と対策

PHP 4.2.xを使っている環境では、mb_eregの全体一致検索に ^ と $ を使っていると、前述のような脆弱性となる可能性があります。^ と $ ではなく、\A と \z を使って全体一致検索を指定するようにしてください…というより、PHP 4.2はとっくの昔のサポートが終了しているので、最新のPHPに移行するようにしましょう。
…と、ここで気になってPHP 4.2がリリースされた時期を調べてみたのですが、
  • PHP4.2.0     2002年4月22日 
  • Windows XP 2001年10月25日(OEM)
いまとなっては化石のようなPHP4.2ですが、リリースされた時期はWindows XPよりも *新しい* のですね。いかに、Windows XPが長くサポートされてきたかをあらためて感じました。

まとめ

大垣さんの指摘に刺激を受けて、古いmb_eregの挙動を調査しました。その結果、PHP4.2.xのmb_eregは複数行モードで動作することを確認しました。
この結果に関係なく、全体一致検索には、\A と \z を用いるようにしましょう。また、PHP4.xを使っているサイト(まだ結構あります)は早急にPHPの最新版に移行しましょう。

2014年4月1日火曜日

2014年3月31日月曜日

ANAの個人情報開示請求により1ヶ月間のログイン履歴が確認できた

先日のエントリ「ANAマイレージクラブのログインを少しでも安全にする運用を考えてみたが見つからない」で紹介したように、ANAの個人情報開示手続きにてAMCホームページへのアクセス履歴が開示されるということなので申し込んでおりましたが、昨日封書にて到着しましたので皆様の参考のために公開します。
ますば、送付案内です。


続いて、アクセス履歴。


これを見て、以下の疑問が生じました。

アクセス履歴の項目

IPアドレスについても開示されると思っていましたが、「※IPアドレスにつきましては、社内規定に則り開示をすることは出来かねます。」とありますが、上記の情報だけだと、自分のアクセスなのか、第三者によるものなのかの判別が難しいと考えます。
Yahoo!のログイン履歴にはIPアドレスが表示されます(参考)し、Googleの最近のアクティビティには市区町村までの地域が表示されます(参考)。
表示されるIPアドレスは原則として自分のものであり、仮に自分以外のIPアドレスがあれば、それは不正アクセスであることから、IPアドレスを開示しない合理的理由が分かりません。
ただし、IPアドレスも加えて、上記にある項目は私が例示として示した項目ですので、さまざまな項目を明記すれば、さらなる情報が開示される可能性はあります。

開示期間について

「過去一ヶ月分のアクセス履歴」とあるものの、いつからいつまでの履歴であるのかが分かりません。上記には、3/11~3/15の履歴が表示されていますが、3月16日移行も私はログインをしています。そこで、開示請求書を見直してみると、「ご請求日」の欄が3月15日となっていました。
これで分かりました。「ご請求日」を起点として、過去1ヶ月間のログイン履歴を表示しているということでしょう。
ということは、2月15日から3月10日までは誰もログインしていないということが確認できたことになります。それより前のことは分かりませんが、この期間中には不正ログインは受けていないことが確認できました。

ということで、あまり期待していなかったANAの個人情報開示請求ですが、はなはだ不満は残るものの、当初の目的としていた情報は一応得られたことになります。
なお、AMCサービスセンターに電話で確認したところでは、通常個人情報請求には500円が必要ですが、今回の不正ログインに関しては、例外として、4月末までは無料で対応しているとのことです。
上記の納得のいかない点については、開示請求書の書き方を変えて、昨日再度請求していますので、届き次第報告いたします。

2014年3月28日金曜日

とあるECサイトのアクセス制御不備

商売柄、脆弱性や侵入事件のニュースがあると背景を調べることが多いのですが、このエントリは、侵入されたサイトを見に行って発見した脆弱性のお話です。
とあるECサイトが外部から侵入されたというニュースを見て、再開後のECサイトを見に行きました。普通に会員登録してログインしてみると、セッションIDの他に気になるクッキーが発行されていました(クッキーの名前と値は変えてあります)。
Set-Cookie: login=123456; path=/
Set-Cookie: loginflg=1; path=/
直感的に、login=123456は内部的なユーザID(ユーザ番号)、loginflg=1はログイン済みであることを示すフラグのように思えました。しかし、まさかね。今時それはありえないアルよ。
そこで検証のために、先ほどとは別のユーザを登録してログインしてみました。すると、以下のクッキーが発行されるではありませんか。
Set-Cookie: login=123457; path=/
Set-Cookie: loginflg=1; path=/
なんということでしょう。loginというクッキーが、1つインクリメントされているではありませんか。この段階で、loginの示す値が内部的なユーザID(ユーザ番号)であることは確実のように思えます。
外部に晒す必要のない会員番号を公開している時点で、よろしくない状況ではあるのですが、まだこの段階では致命的な脆弱性であるとまでは言えません。たまに、意味ありげなクッキーを吐いていても実際には使っていなかったり、表示のためだけに使っている場合もあるからです。

そこで、ブラウザのすべてのクッキーを削除した後上記のクッキー(123456等)のみを再セットして、会員情報を表示するページを閲覧してみました。すると、私の個人情報が表示されるではありませんか。次に、loginを123457に変更して個人情報ページを閲覧すると、2番目に登録した方の個人情報が閲覧できました。うーん、これで確定のようですね。クッキーloginの数字を変えるだけで任意のユーザになりすましができてしまいます。しかも、この数字は連番ですので、推測が容易です。

私は拙著「体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践 」にて、自動ログインの危険な実装例として以下の説明を書きました。

体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践 P330より引用

引用した箇所は自動ログインとしての説明であり、上記はログイン結果の保持という違いはありますが、「かなり極端な例」として紹介した実装を21世紀の今日、ECサイトのログインで見かけたというのはいささか驚きでした。

では、どうすればよいかですが、読者の皆様には今さら説明する必要もないでしょうが、セッション変数にログインユーザを保持すれば問題ありません。クッキーとは異なり、セッション変数は第三者からも利用者からも変更はできないからです。

ということで、ここから得られる教訓は下記の通りです。
  • 認証後にログインユーザ名を保持するにはクッキー等ではなくセッション変数を使おう
  • 侵入被害にあった後サイトを再開する前に、セキュリティの専門家にチェックしてもらおう
なお、この脆弱性はIPAに届け出を行い、既に修正されていることを確認済みです(取扱い番号 IPA#19289197)。届け出の際の脆弱性は「セッション管理の不備」としていましたが、上記の実装だと「アクセス制御の不備」の方が妥当な気がします。容易に推定できる番号だけで認証状態になってしまうからです。

2014年3月17日月曜日

ANAマイレージクラブのログインを少しでも安全にする運用を考えてみたが見つからない

既に「ANAの不正ログイン事件について徳丸さんに聞いてみた」で書いたように、ANAマイレージクラブ(AMC)のWebサイトに不正アクセスがあり、利用者 9人、計112万マイルがiTunesギフトコードに不正交換されました。ITproの記事を引用します。
ANAに申告があった9人分、計112万マイルについて、3月7~9日の間にiTunesギフトコードへ交換されていたことを確認したという。【中略】同社は10日18時30分以降、iTunesギフトコードへの交換サービスを停止した。不正ログインの手段など攻撃の詳細や、他にも不正ログインがあったかについては調査中という。
ニュース - ANAマイレージクラブへの不正ログインで112万マイルが詐取、住所なども閲覧可能に:ITproより引用
攻撃があってから一週間たちますが、まだANAに申告があった利用者の被害しか発表されていません。上記9名以外にも、マイル不正交換があった可能性はありますので、AMC利用者の方は一度確認をお勧めします。
さらに、不正交換はないものの個人情報が流失した利用者は相当数あると想定されるものの、攻撃者が単に不正ログインして、個人情報を閲覧されただけでは、利用者には確認の手段がありません。

ANAマイレージクラブ・サービスセンターに電話してみた

では、私のアカウントは大丈夫なのだろうかと、こちらのサイトで案内されていたANAマイレージクラブ・サービスセンターに電話で問い合わせてみました。「私の個人情報は漏えいしてないのですか? それは分からないのですか? 」と問い合わせたところ、上席に替わりますということになり、上席なる方の説明によると、個人情報開示手続きにて、ある範囲のアクセス履歴を開示できるということでした。
電話で聞く限り、開示手続きにて開示される履歴は、マイル交換や個人情報の変更に関するもので、それは敢えて開示請求しなくてもメールにより都度通知されるので、利用者も把握できる情報です。利用者が把握できない情報として、IPアドレスやUser-Agentの情報も開示されるようですが…
一方、単にログインしただけとか、ログインした後個人情報を閲覧しただけでは開示の対象にならないようです。さらに開示の期間は直近の1ヶ月間と説明されました。これでは意味がないなと思いつつ、どのような情報が開示されるのか開示請求をかけてみました。結果については、別途報告したいと思います。

AMCサイトはパスワードの定期的変更の効果が多少ある

先のブログエントリで書いたように、AMCサイトは以下の困った特徴があります。
  • パスワードが4桁数字であり不正ログインの可能性が高い
  • 他者がログインに成功しても、それを利用者が知る手段がない
  • 不正ログインがあってもサイト運営者がそれを検知できていない(実績として)
  • 不正ログインに成功しても直ちに悪用されず、後からマイル交換等の悪用をする動機が攻撃者側にある
最後の項について補足します。先のエントリでは、攻撃者はパスワード収集とマイル交換のフェーズを分けて実行したのではないかという推測を書きました。これに加えて、不正ログインに成功した時点ではマイルは交換の対象になっていないが、数ヶ月後であればマイルが増えていて交換の対象になる可能性があります。すなわち、直ちに悪用しないで、後から悪用する動機が攻撃者にはあることになります。
AMCサイトの上記の特性から、AMCサイトではパスワードの定期的変更が一定の効果を持つことになります。これは、以前「パスワードの定期的変更について徳丸さんに聞いてみた(2)」で、「理論的には、次の条件を満たすサイトを使わないといけない場合は、パスワードの定期的変更が効果がなくはない」と指摘した通りです。すなわち、
  • 不正ログインの確率が下がる訳ではない
  • 個人情報が漏えいする確率は変わらない
  • 不正ログイン時点でマイルを直ちに交換せず後からマイル交換するという行為を防げる可能性がある
ということで、効果も、確実性も高い訳ではありませんが、一定の効果があることは認めなければなりません。しかし、これは、パスワード定期的変更が一般的に効果があるという証拠ではありません。むしろ、「AMCサイトは、パスワードの定期的変更くらいしか防衛手段がない残念なサイト」である証拠であると私は考えます。

ただし、上記シナリオに限定すると、パスワードの定期的変更よりも効果的な防御策があります。それは、
  • マイルが貯まったら直ちに交換する
という方法です。マイルが貯まるタイミングは利用者が分かるので、パスワードの定期的変更よりも確実です。ただし、「マイルをたくさん貯めてプレミアムなサービスと交換したい」という希望はあきらめなければなりません。たくさん貯まる前に窃取される可能性があるからです。その場合はパスワードの定期的変更も、あまり意味はないかもしれません。マイルが一定量貯まっていれば、その時点で不正交換されてしまうかもしれないからです。

そもそも、マイルの不正交換が心配なのであれば、不正交換があった時点で運営者に申告して補填してもらうことが筋でしょう。ということで、パスワードの定期的変更を推奨するわけではありません。

アカウントロックを試してみた

既に色々なところで書かれているように、AMCサイトにはアカウントロックの仕組みが実装されていますが、何回パスワードを間違えた段階でロックされるかは書かれていません。そこで、実験で試してみました。
自分のID(お客様番号)を固定して、パスワードの方を変えながら試していくと、10回パスワードを間違えた後に以下の画面が表示されました。


この画面は固定のURLのようです。

アカウントがロックされても利用者にはメール通知されないようです。これは問題だと感じます。第三者から攻撃されていることを、利用者は知る術がないことになります。

次に、アカウントロックの解除はどうすればよいでしょうか。具体的な方法は書いてありませんが、上記の画面には、意味ありげに「パスワードを変更される場合はこちらへどうぞ。」と書かれていますので、こちらに従ってパスワードリセットしたところ、アカウントロックも解除されました。これ自体は妥当な仕様でしょう。正当な利用者がアカウントをロックさせてしまうのは、パスワードが分からなくなってしまったからという理由が多そうで、その場合はパスワードリセットすることで、ロックも解除されるという仕様のようです。
なお、パスワードリセットのためには、登録済みメールアドレスでメールが受け取れることと、会員番号、電話番号、生年月日が必要ですので、試してみる方は上記を確認してから…というより、アカウントロックを試す場合は、先にパスワードリセットができることを確認してからの方が無難でしょう。

認証連携を積極活用するという裏技の検討

前にも書きましたが、AMCサイトはGoogle等と認証連携していることを崎村さんから教えていただきました。
「Webパスワードをオフにする機能」は現時点ではないわけですが、facebookの私のウォールでの会話(非公開)で @keikuma さんから以下の指摘をいただきました。非公開の会話ですので、keikumaさんの許可を得て以下に引用します。
これ、ANAに電話したんですが、同一アカウントに対する試行回数の制限は入っているのだそうです。認証連携があるので、試行回数制限でパスワードをロックしたまま、連携認証ができないかなぁと思ったのですが、今、ちょうど出張の準備が忙しくて、ロックされて面倒な事になると困るので、試せていません。
利用者がわざとアカウントロックした状態で、Google等の認証連携でログインできれば、認証連携のみでの運用ができ、2段階認証等も活用できるというアイデアです。このアイデアについても、先にアカウントロックを試したついでに確認してみました。その結果、@keikumaさんの予想(希望)通り、
  • パスワード間違いでアカウントロックされた状態でも、認証連携ではログインできる
ことを確認しました。
ただし、おそらくサイト運営者の意図した使い方ではないと思われるので、以下に書くような副作用も予想されます。
  • アカウントロックされた状態で認証連携でログインできることは、バグとして将来変更になる可能性がある
  • アカウントロックは、利用者が解除しなくても、一定期間経つと自動的に解除される可能性がある
  • あまりに長期間アカウントロック状態が続くと、アカウントが凍結される可能性がある
ということで、「こうするとよい」という意味ではなく、あくまで調査結果の報告という形でみなさまの参考情報として紹介します。
【追記】公開直後に気づきましたが、意図的にアカウントロックしておいて、使う時はパスワードリセットして使う(認証連携が使えればそちらを使う)という運用はありそうです…が、パスワードリセットしてサイトを使った後は再度アカウントをロックしなければならず、「怪しい行為」として疑われるかもしれません。疑われないにしても、自動的にアカウントロックが解除される可能性はあり、その場合は、この運用は難しいといえます。

まとめ

AMCサイトのログインの仕様について調査した内容を以下にまとめます。
  • AMCサイトのアクセス履歴は個人情報開示請求にて一定の内容が開示される
  • AMCサイトはパスワード10回間違いでアカウントロックになる
  • アカウントロックのメール通知は来ない
  • アカウントロックはパスワードリセットによりロック解除される
  • アカウントロックされた状態でも認証連携ではログインできる
  • 意図的にアカウントロックを活用した裏技があるが、推奨するわけではない
  • 特定の利用者を狙ったパスワード攻撃が成功する確率は 0.1% であり、この確率を減らす方法は(裏技は別として)利用者にはない
  • 不正ログインから時間をおいてマイルを窃取する攻撃に対してはパスワードの定期的変更が一定の効果があるが、もっと良い方法はマイルが貯まったら直ちに交換すること
ANAに対する要望は以下の通りです。
  • 不正ログインの全容(被害者の数など)を早く公開して欲しい
  • 不正ログインされた利用者には個別にその旨を連絡するか、不正ログインの有無を確認する機能を実装して欲しい
  • ログイン通知機能やログイン履歴閲覧機能を実装して欲しい
  • アカウントロックのメール通知を実装して欲しい
  • パスワードの仕様をすぐに変更できない場合は、パスワード認証の停止などの代替策を早期に実装して欲しい
  • パスワードの仕様を安全なものに変更して欲しい

ANAのサイトは、心配だから使わないということは難しいわけで、一利用者として早期の改善を希望致します。

フォロワー