<< [Perl]Regexp::Assemble を使って連想配列のキーに正規表現を使う | main | iPhone 3GS 買った >>

クライアントの要望を満たすと、セキュリティ的に問題がある。どうしたらいい?

このエントリーを含むはてなブックマーク hateb
受託開発で困る部分のひとつ。

1. ログインに失敗したときのメッセージ

簡単な例を出してみよう。ID/Password を入力させるようなログイン画面で認証に失敗した場合、「ID またはPassword が正しくありません。」というようなメッセージを出すのが通例だ。当然システム側では、ID が間違っているのか、Password が間違っているのか区別することはできるのだが、親切に「ID が正しくありません。」とか「Password が正しくありません。」とかというようなメッセージは出さない方がいいとされている。これは親切なメッセージを出すと、悪意の第3者になりすましログインのヒントを与えてしまうことになるからだ。適当なID/Password でログインを試みて、親切にエラーメッセージが出し分けされると、その適当に入れたID が存在するID かどうかを判定できてしまう。ひとたびID が判定できれば、あとはPassword の方を総当たりなどでチェックするだけでログインできてしまうということになる。実際にはID がわかったところで、Password 総当たりでログインするというのはそんなに簡単なことではないのだが、ユーザーが比較的簡単なパスワードを設定している場合は、簡単にログインされてしまうということももちろんある。

こういう部分は、どういうメッセージにしてほしいとか、クライアントから細かく指示されないことも多く、その場合こちらから提案することになる。業界の通例で、とくに上記の理由などを意識せずに、正しいエラーメッセージを提案している人も多いと思う。しかしそういうケースだと、ひとたびクライアントから、「ユーザーにわかりやすいようにエラーメッセージを出し分けて」といわれたら、すんなりその要求をのんでしまうのではないだろうか。

慶應オンラインは、このセキュリティ的には正しくない方のメッセージで実装されている。管理者に指摘したところ、ユーザーの利便性の方が重要とのことだった。ユーザーの利便性とセキュリティの堅牢さは、往々にしてトレードオフの関係にあるので、脆弱にすることのリスクと、それによって得られる利便性を比較して、利便性の方が高ければ、そちらをとるというのもありなのだろうか。ただ、僕は慶應オンラインのユーザーとして、このシステムを使うのはとても嫌だ。

【参考】
慶應オンライン

2. パスワードリマインダーに失敗したときのメッセージ

上記と似たような例として、パスワードリマインダーのエラーメッセージの問題がある。簡単なパスワードリマインダーを例に考えてみよう。ユーザーが会員登録時に入力したメールアドレスを入力させて、そのアドレス宛に初期化したパスワードを送るという方法だ。このときに、メールアドレスを間違えて入力すると、「そのメールアドレスは登録されていません」というエラーメッセージが出るサイトが多い。よく考えれば、これも当然、そのメールアドレスがそのサイト内に登録されているかを判別できてしまう。上記のログイン認証の例では、曖昧なメッセージをだして存在チェックができないようにしているサイトでも、パスワードリマインダーでは簡単にこういうことをやってしまっている。パスワードリマインダーでのエラーメッセージは、僕は下記のメッセージで提案することが多い。

メールアドレスが正しくても間違っていても同じメッセージを出さないといけないので、こんな感じになる。
ご入力頂きましたメールアドレス宛に、初期化したパスワードをお送りいたしました。
ご入力頂きましたメールアドレスと、ご登録頂いておりますメールアドレスが異なる場合は、初期化メールが送信されません。
ただ、これはログイン認証の失敗よりユーザービリティに与える影響は大きいように思う。実際、この提案はクライアントに嫌な顔をされることが多く、たいていはメールアドレスの存在チェックができてしまうようなメッセージに落ち着く。ただし、当然そのリスクはクライアントに伝えたうえでだ。

3. SSL のかかっているフォームの内容をメールで飛ばす

上記2つの例はまだかわいいもので、クライアントがトレードオフのどちらをとったのか、そのポリシーが、ユーザーにも見える。ところが、SSL のかかっているフォームの内容をメールで飛ばすとなると、話は変わってくる。フォームにSSL をかける場合、ユーザーが入力したデータも暗号化された経路でクライアントの手に届かないと意味が無い。簡単なのはCSV ファイルなどに蓄積し、SCP(FTP はダメ)などでそれをダウンロードしていただく方法だ。ただ、クライアントのリテラシー次第では、SCP によるダウンロードは敷居が高いこともある。その場合、簡単なダウンロードの仕組みを提供してあげる必要がある。もちろんその部分の開発コストもかかる。そうなると、クライアントは、メールで情報を飛ばしてくれる方が、開発コストがおさえられるうえに、自分たちも楽できるから、そうしてくれと言い出すことが多い。リスクを説明しても、「実際、経路上抜かれることなんてないでしょ?」とか、「見た目にはユーザーにはわからないんだよね?」とか、平気で言ってくる。

開発会社がクライアント企業のポリシーに口を出すのも筋が違うので、泣く泣くこういう開発を請け負うこともあるが、果たして正しい対応とはどういう対応なんだろうか。

また、セキュリティに配慮した高い見積もりが、セキュリティに配慮していない安い見積もりに負けるという構図は、どうすればひっくり返るのか。
| Web技術 | 17:49 | comments(8) | trackbacks(1)
この記事のトラックバックURL
http://en.yummy.stripper.jp/trackback/1248086
トラックバック
メールって盗聴されますか?
久々に興味を持つネタに出会った。(最近、みんな飽きちゃったのか、こういう熱い話、はてブで見かけなくて) ブログが続かないわけ | クライアントの要望を満たすと、セキュリティ的に問題がある。どうしたらいい? 1.ログインに失敗したときのメッセージ ログイン失
| F's Garage | 2009/06/26 3:22 PM |
コメント
>1. ログインに失敗したときのメッセージ

ログインIDが任意なら良いのですが、メールアドレスとしているシステムだとIDバレ即そのサイトを利用している事がバレるというパスワードリマインダーと同様のリスクが発生してしまいますね。

メールアドレスがIDのシステムで、サインアップ時にメールアドレスが存在する事を確認するメールを投げそこからワンタイムURLで最終確認させる仕組みを組み合わせた場合に、故意に他人のメールアドレスを登録されると当人が登録しようとした時に「すでに登録されています」と返してしまうという問題が。


メールアドレスがIDの場合、申し込み手続き自体は既登録のアドレスが登録されようとした時は、そのまま処理を進めてしまい、悪戯だった場合は確認メールを無視すれば既登録ユーザーは困らないし、携帯アドレスだった場合はメールアドレス自体は既登録だけど別人というケースがままあるので、情報を上書きして利用してもらうフローを想定するのが適切だと思います。
(ある意味パスワードリマインダーと同じフローになるわけです)

サインアップ確認のワンタイムURLがワンタイムじゃないから、確認メールが出せなくなってサインアップできなくなる問題というのもありましたが、不特定多数のシステムではメールアドレスがIDというのは脆弱性やバグの温床になりやすいように思います。

>3. SSL のかかっているフォームの内容をメールで飛ばす
>開発会社がクライアント企業のポリシーに口を出すのも筋が違う

ポリシーよりも、相手企業のインフラ部署との折衝が非常に面倒ですし、それが無ければ今度は提案の規模や内容が大きく変わって、お客さんが本当に欲しかったものから話をズラされている気分になってしまいます。
そこまで提案するとなれば、インフラ構築として長期的に運用も背負わなければ、たとえセキュリティ的に正しくても相手にはインフラ押し売り業者に見られてしまいます。

システム開発のみ受注している場合は、最初から「インフラ制約」と割り切って受け入れるしかないのかなと。
プランC的なハイグレードなオプションとして、なぜそうしたほうがいいのかという提案資料を作っても採用されるのはせいぜいコスト的に折り合いをつけたプランBですからね。
堅牢なものを構築したいという理想が勝っている場合は、そもそも受託開発ではなくASPとかアプライアンスで売るのが適切なんだと思います。
| とおりすが | 2009/06/25 9:23 PM |
コメントありがとうございます。
メールアドレスの存在チェックを伴うようなユーザー登録フローは、仰る通りのフローが良いと思います。既に仮登録がなされているメールアドレスも上書きで再登録できるという流れが最適でしょう。

また、ID = メールアドレスにするのが脆弱性の温床になるとすると、ここにもまた、セキュリティの堅牢さとユーザビリティのトレードオフがあるということになりますね。やはり、ユーザーは自分のIDを覚えておけないひとも多いですから。

最後の部分に関しては、仰ることは正論だと思います。しかし、理想ではないと思います。堅牢なものを構築したいという理想を、受託開発の現場に持ち込むことは間違っていることでしょうか?

こういう情報を発信し続けることで、少しずつでも状況が変わることを願いつつ、仮に難しいことだとしても、僕は理想を求めたいと思います。
| junichiro | 2009/06/25 11:50 PM |
>こういう情報を発信し続けることで、少しずつでも状況
>が変わることを願いつつ、仮に難しいことだとしても、
>僕は理想を求めたいと思います。

揚げ足っぽくなって、先に、ごめんなさいなんですが、
それって「エンジニアのこだわり」以上の何者でもなくないですか?


>「実際、経路上抜かれることなんてないでしょ?」


「かくあるべし」ではなく、これに対する具体的なリスクが説明、実証できなければ、結局、リスクマネジメントの話でしかないので、解決しないと思います。


で、そういうのを批判したいわけじゃなくって、


もし、自分の思いが強くあって、お客さんを変えたいと思うのなら、技術の力で変えてみませんか?と思いました。

受託で、全部のお金をお客さんからもらわないといけないから自分の理想は何も実現できない、のではなくて、実現できるようなプロダクトをフリーで公開して、格安で使ってもらえるとか、もしくは、いくばくかの保守料だけで使ってもらえる製品を提供して、数を集めるモデルにするとか、いっそその部分だけASPにするとか、そういうことはできないのかな?!と。

| f-shin | 2009/06/26 3:00 PM |
あ、ごめんなさい。長い文章をざっくりカットしたら、意味が全然通じない話を書いてしまいました。

私が言ってることは、

「SSL のかかっているフォームの内容をメールで飛ばす」

だけを解決する方法でした。

アンケートフォームや申し込みフォームなら切り出すことできますよね。
| f-shin | 2009/06/26 3:05 PM |
f-shin さんコメントありがとうございます。

> それって「エンジニアのこだわり」以上の何者でもなくないですか?
という部分に関しては、まったくそうは思いません。
これって、技術の話じゃなくて倫理の話ですから。

例えば、W3C のValidate を絶対に通さないと気がすまない、とかは第3者にはほとんど何の影響も与えないので、こういうのは「エンジニアのこだわり」として片付けてしまっても良いと思いますが、ここであげた話は、ユーザーが自分の送信した情報が暗号化されていると信じてるのに、実はそうではないというのが問題で、つまりユーザーに嘘つくことになるけど、それでもいいの?という話です。

仮に自分がエンジニアじゃないとしても、1ユーザーとして、バックエンドの経路で、暗号化されていないなら、その旨を明記しろと、そう思うわけです。ですので、自分が発注側だったとしても、知っていればこだわりたい部分です。要するにエンジニアのこだわりというより、ユーザーへの責任の倫理観の話です。

倫理厨とか、理想論とか、そういわれてしまえば、それは甘んじて受け入れますが、「エンジニアのこだわり」というのは受け入れがたいですね。

後半部分は非常に納得させて頂きました。こういう製品を世に出すことで、少しでも変えて行くことは可能ですね。ただ、クライアントがメールより操作が簡単だと思ってくれないといけないので、その部分はまた少し敷居が高い部分ではありますが。
| junichiro | 2009/06/26 3:26 PM |
なるほど。

とてもおっしゃることは理解をしています、という上で、批判とか論破とかそういう意味じゃなくて、もし同じ会社で同じサービスに携わっているチームだったら、僕はこう言うと思います。

「ユーザーに嘘つかない表現をした上で、メールで送りましょう」

かな。

そもそもSSLの信頼性と、メールで送ることは筋が違うと思うんですよね。

つまり暗号化経路をどこまでつなげるか?という意味では、SCPで送っても、その先のワークフローで社内がexcelだったら意味あるんかい?とかですね。

SSLの通信は、あくまでもフォームの送信のスコープだと思います。例えば、正しいドメインに送信してることを保証しますとか、そういうあたりを信頼性の論点にしたい。

オレオレ証明書じゃダメで、verisignとかでサーバ証明書を取るのはその辺だと思うんです。

いずれにせよ、技術を理解できないユーザーを過大に不安にさせる表現はアウト。

そうならない上で、誇大にならない表現を考えてうまくやるというのが考え方かなと思います。

| f-shin | 2009/06/26 4:07 PM |
おっしゃるとおりですね。

僕が、ひとつ気にするポイントは、エンドユーザー(サイトのユーザー)に通知している(もしくは当然そう思うであろう)セキュリティを維持できているかどうかということです。

僕自身、SSL はサイトの正当性の証明の意味合が強く、データが暗号化されているということの方が副産物であると考えることもあるのですが、それこそ非エンジニアの一般の方は、「とにかく暗号化されているから安全」と思っていると思います。

で、その暗号化の範囲が、なんとなくですが、「インターネット上を流れるところすべて」と漠然と思っている気がするのです。そのため、やはりメールをプレーンで飛ばすのはNG で、社内のワークフローでExcel は仕方ないかなと、感じるのかもしれません。

極端な話、どこからどこまでは暗号化されていて、ここから先はプレーンに流すよというようなことを明記するのが筋なのかもしれませんが、さすがにそれは有り得ないですし、クライアントに提案できるわけもありません。

実際、セキュリティによる被害の期待値というのは、漏洩リスク(漏洩の可能性) × 漏洩時の被害額です。正確に見積もることはできませんが、f-shin さんが考えるように、かなり小さいものだとは思います。それこそ、ユーザービリティや開発コストと比較すると、無視したくなるようなものかもしれません。

つまり、受託側には説明責任はあるが、発注側はそれを理解した上で自由に選択すればよく、受託側は発注側の決定を実装すれば良い。

そんなところですかね。
| junichiro | 2009/06/26 4:38 PM |
もちろん長期的に見たら、やっぱり発注側が適当なのはマズイです。

結局、excelファイルを漏洩しちゃいました、というのであればみんな不幸ですから。

そういう意味では、漏洩の危機もコストも一番高いのはSCPを使うが使うまいが「データを受信した後」ですね。

受託というスコープで打算的な表現をしてしまえば、メールで送るのはさほど問題でなく、その後、運営側が情報漏洩した時に、受託側が文句を言われないような証明は取っておくべきだし、作り手として、本当にヤバイものを見極めて、頑として作らないという姿勢の問題なのかもしれません。

例えば、ログインフォームがパスワード検証機になってしまうのは、基本的によろしくない。
しかし、それだけじゃリスク判断の程度問題になるかもしれません。

もし、そのサイトがクレジットカード番号が漏洩するリスクや不正利用のリスクとセットであるのであれば、明らかなセキュリティリスクとして説得するべきでしょう。

総当りでアタックするのは簡単だし、それでカード番号を抜かれた事例も実際に起きています。サイトが大きくなって忙しくなったら後から直すの大変ですよ、と。

そこまでの話が言えるのであれば、さすがに理解を示してもらえると思うんです。

結局は、技術の良し悪し(かくあるべし)単体では人を説得するのは難しくて、仕様にあわせた具体的なリスク可能性とセットなのかなと思ったりします。(よくそういう話をします)
| f-shin | 2009/06/26 6:37 PM |
コメントする