| « Tomcatの管理者は大忙し? | プログラミングではホワイトリスティングが基本 » |
ホワイトリストとブラックリスト - Proactiveセキュリティ対策 vs. Reactiveセキュリティ対策
「プログラミングはホワイトリスティングが基本」にブラックリストもホワイトリストもどちらも同じ事を言っていて違いが分からない、とコメントを頂きました。
http://pfrb.blog114.fc2.com/blog-entry-5.html
ホワイトリストとブラックリストは単純な場合は分かりやすいコンセプトですが、ちょっと複雑になると分かりやすいようで境界が分かり辛いコンセプトです。
メールのホワイトリストとブラックリスト
メールを例にホワイトリストとブラックリストの違いと境界の分かり辛さを解説します。
フォローアップ
メールにおける単純なホワイトリスト(許可リスト)とは受け取りたいメールアドレスを指定し、そのメールアドレス以外を拒否する機能です。私からのメールを受け取りたければ yohgaki@ohgaki.net をホワイトリストに登録します。
ブラックリスト(拒否リスト)は反対に受け取りたく無いメールアドレスを指定し、そのメールアドレス以外からのメールは受け取る機能です。私からのメールを受け取りたくなければ yohgaki@ohgaki.net を登録します。
単純な場合は、非常にシンプルで分かりやすいコンセプトです。
境界が曖昧なホワイトリストとブラックリスト
メールアドレスの指定にワイルドカード(任意の文字列を表す"*")を利用可能にすると、ホワイトリストとブラックリストの境界は非常に曖昧になります。
私がアカウントを取得する場合、yohgakiが利用可能な場合はyohgakiをユーザ名として登録しています。私がyohgakiで始まる複数のアカウントを持っている事を知っている知人はyohgaki@ohgaki.netでも、yohgaki@gmail.comでも、yohgaki@yahoo.co.jpでも受信できるようホワイトリストに"yohgaki*"を登録するかも知れません。
反対にブラックリストのユーザは"yohgaki*"を登録して拒否するかも知れません。
"yohgaki*"をホワイトリストに登録したユーザは"yohgaki*"以外をブラックリストに登録したのと同じです。反対に"yohgaki*"をブラックリストに登録したユーザは"yohgaki*"以外をホワイトリストに登録した事になります。しかし、目的が私からのメールを許可または拒否したい為に"yohgaki*"をホワイトリスト、ブラックリストに登録したとすると、どちらのリストも目的を果たせなくなる可能性があります。
yohgakiがアカウント名として取れなかったのでyohgaki123, yohgaki456というユーザ名を取得したユーザがいたとすると、"yohgaki*"をホワイトリストに登録したユーザの意図に反して、私が所有しないyohgaki123, yohgaki456のユーザ名の持つメールアドレスからのメールが許可されます。"yohgaki*"をブラックリストに登録したユーザは私からのメールだけを拒否したかったのに、私が所有しないyohgaki123, yohgaki456のユーザ名を持つメールアドレスからのメールまで拒否してしまう事になります。
この様にワイルドカードを使い出すと一つのルールで複数のアドレスを許可できたり、拒否できるようにすると、拒否しなくないアドレスまで拒否してしまいます。基本的なコンセプトは変わらないのですが、どちらもその基本コンセプトを達成することができなくなり、境界が曖昧になってきます。
プロアクティブなセキュリティ対策とリアクティブなセキュリティ対策
メールの例で示したようにホワイトリスト、ブラックリストというコンセプトだけでは境界が分かり辛くなります。
プロアクティブ(積極的)なセキュリティ対策とリアクティブ(受動的)なセキュリティ対策というコンセプトでは境界は曖昧になり辛いと考えています。こちらの方が、より分かりやすく実践しやすいと考えているので「Webアプリセキュリティ対策入門」では、セキュリティ対策のコンセプトをプロアクティブな対策とリアクティブな対策に分類し、基本的にプロアクティブなセキュリティ対策を選択するようお薦めしています。
プロアクティブなセキュリティ対策とは、予測不可能なリスクも回避できるよう安全性を保証できる対策のみを採用するセキュリティ対策です。プロアクティブなセキュリティ対策では行っても良い事を定義します。もちろん「行っても良い事」は安全である事が保証できなければなりません。安全であることを保証した「行っても良い事」だけを許可する為、予測不可能なリスクも回避できる可能性が高くなります。(JavaScriptインジェクションが良い例です)
リアクティブなセキュリティ対策とは、既知のリスクを回避できるよう、危険性を防止する対策を採用するセキュリティ対策です。リアクティブなセキュリティ対策では、行ってはならない事を定義します。「行ってはならない事」の危険性は確実です。危険と分っている「行ってはならない事」を禁止するため、予測不可能なリスクを回避する事は出来ません。(こちらもJavaScriptインジェクションが良い例です)
ホワイトリスト型のセキュリティ対策とは基本的にはプロアクティブなセキュリティ対策です。安全であると確実に分っている事だけを許可します。ただし、メールの例の様に"yohgaki*"は大垣靖男からのメールアドレスからとして処理する、と定義するのは「予測不可能なリスクも回避できるよう、安全性の保証できる対策(この場合はメールアドレス)のみ採用する」といった考え方に反する危険なルールと言えます。
プロアクティブなアプローチでは、何が安全で何が危険か常に考えながらセキュリティ対策を考えます。リアクティブなアプローチでは何が危険か考えながらセキュリティ対策を考えます。リアクティブなアプローチでは「何が安全か」という視点が無いため、危険を回避できない事が多くなります。
プロアクティブなアプローチは万能か?
プロアクティブなセキュリティ対策が万能か、というと実世界ではどう頑張ってもプロアクティブなセキュリティ対策が取れない場合もあります。例えば、データベースにデータを保存した場合、そのデータがどの様に利用されるか予め分かる事は少ないです。脆弱性があるアプリケーションによってデータベースに保存したデータが利用され、攻撃に利用されるかも知れません。
しかし、どのように利用されるか分からないからと言ってデータベースにデータを保存する場合にどんなデータを入れても良い分けではありません。テキストデータであるなら、最低限文字エンコーディングが正しい事を確認してからデータを保存すべきです。
データベースによっては、自動的に文字エンコーディングが正しいかチェックします。DBMSは文字エンコーディングが正しいかチェックするのでアプリではチェック無しでも大丈夫、とはプロアクティブな考え方のセキュリティ対策では考えません。入力が予定している形式と異なる場合は未知のリスクが発生する可能性がある、と考え正しい形式であるか、入力を受け取った時点でチェックします。データベースに保存する、しないは関係ありません。
リアクティブなアプローチの対策を先に考えてしまうと、プロアクティブなアプローチの対策の出る幕はありません。リアクティブな対策の方がプロアクティブな対策より採用しやすいからです。リアクティブなアプローチでは抜け穴を許してしまう可能性が非常に高く、システム構築など、高いセキュリティが要求される場合にはリアクティブな対策ばかり採用していては安全性の高いシステム構築は期待できません。
プロアクティブな対策は万能ではありませんが、可能な限りプロアクティブな対策を先に検討し、採用する事が重要です。例えば、HTMLタグの属性をユーザが選択できるようにするなら、属性値として安全な"アルファベットのみ"の文字列なら許可する、対策を選択するよち、属性値がリストとして定義可能なら、リストに載っている属性値のみを許可する対策を選択すべきです。
ホワイトリストはプロアクティブ、ブラックリストはリアクティブ
違いが分かり辛くなってしまいがちなホワイトリスト的なセキュリティ対策とブラックリスト的なセキュリティ対策ですが、プロアクティブとリアクティブと考えると分かり辛くならないのでは無いでしょうか?
プロアクティブ(ホワイトリスト):確実に安全である物のみを許可
リアクティブ(ブラックリスト):悪いと分かっている物のみを拒否
システム構築の場合、ほとんどの要素が制御可能であるためプロアクティブな対策に大部分に採用可能です。
どちらのアプローチを採用した方が安全なシステムが出来上がるか?議論の必要は無いと思います。
バランスも大事
全ての仕様を厳密にプロアクティブなアプローチに従うと、アプリケーションの仕様、プロジェクトの進行やコストに許容しがたい影響を与える場合があります。私は何事も原理主義は良くないと考えています。状況に合わせて柔軟であることも非常に重要です。
どちらも何が言いたいのか良く分からない、という疑問に対する答えになっていれば良いのですが、どうでしょう?
# 徳丸さんのページを読む前に書いたのでポイントがず
# れているかも知れませんが、その場合はまた書きます。
3 コメント
前回あたりから思っていたのですが、一般的な「ホワイトリスト」という言葉の使い方ではないような気がします。
根本的に「プロアクティブな対策」を推奨することと、ホワイトリストを推奨することは全く対応が異なる話だと思います。恐らく、セキュリティをやっている人間なら誰もが理解してると思いますが。
「安全なものしか通さない」というプロアクティブな考えは、セキュリティでは常識です。しかし、その方法は色々あるわけですよね。
例えば、数字x桁ならば受け付ける(それ以外ははじく)という対策は、一般的にホワイトリストとは呼びませんよね。
それと、ホワイトリストが現実的でない、といっている人達も当然、上の常識は判っていて、出来るのなら当然やっているが、話題に上がっていた、XSS等といった攻撃手法を防ぐ、という幅広い話には、ホワイトリストでは対策出来ないと言っているだけではないでしょうか。シチュエーションが限定されているならばともかく、常識的に考えて「XSSを防ぐにはホワイトリストですよ」とは言えないと思います。
話の発端は、なんでホワイトリストを説明するのにXSS Cheet Sheetをだすのか、という所だったかと思いますが、あれは一般的にみてもあきらかに誤解を招くような記述だと思いました。誤解する人がわずかだが居るようだ、ではなく、誤解しない方がレアケースでしょう。
なにより「いじわるな」と本人で認めているのは、全くいかがなものかと。
再度、上記のようなエントリを作成しました。
『続・ホワイトリストとブラックリスト』
http://pfrb.blog114.fc2.com/blog-entry-6.html
時間もあまり無かったので「ホワイトリストの作り方」はちょっと不親切な書き方でした。私もバリデーションは全てホワイトリストでやるべきだ、とは考えていません。このエントリで紹介したようにホワイトリストのつもりでホワイトリストになっていないケースも少なくありません。「ホワイトリストの作り方」で紹介したXSS Cheat Sheetを見れば、生半可なブラックリストなど全く役に立たない事が5分もあれば分ると思います。(英語サイトのなので敷居が高いのかな...)
開発やプログラミングで、セキュリティ上、最も大切なのは問題に対する「姿勢」だと思っています。受動的なセキュリティ対策は非常に採用しやすいです。設計の問題、入力/出力先の仕様など理解せず、問題が見つかって、分ってからから対処するのですから当たり前です。
能動的な対策は多くの手間が必要となります。設計上の問題、入力/出力先の仕様を正しく理解してから作る事が前提となります。全ての開発者に幅広く、そしてレベルの深い知識を要求する事は、コストが非常に高く、現実的はありません。しかし、「7つの習慣」ではありませんが「姿勢」を身につける事は容易です。
筆者はUS CERTとMSが2000年にXSS問題の提起をした時にプロアクティブなセキュリティ対策の視点から、文字エンコーディングは厳格に扱うべきと考えていました。2000年時点では壊れた文字エンコーディングを利用した、具体的な攻撃手法などを考えつきませんでしたが、隠れたリスクを予想はしていました。
実際に複数文字エンコーディングや壊れた文字エンコーディングを利用したXSSやSQLインジェクション、XMLインジェクションは何年も経ってからPoCが発表されました。
このような事例は他にもあります。スタックスマッシング攻撃が実用化された当初はヒープ領域のメモリ管理問題はセキュリティ上大きな問題ではないと認識されていました。しかし、研究が進むとヒープ領域のメモリ管理問題もスタックメモリ管理の問題と同様に任意コード実行が可能である事が分りました。
# 個人的にはこの経験がセキュリティ対策を能動的に考え、実践
# する事の重要性を学ぶ機会になりました。
経験に学ぶより、歴史に学ぶ方が遥かにコストが少なくなります。
歴史的にはブラックリスト的、受動的なセキュリティ対策は、無意味とは言いませんが、コレに基準を定めると安全なシステム構築には有害である事は証明されていると考えています。
しかし、システム開発の現場は理想主義だけではこなせないのが現実です。従って、能動的な対策を基本に置きつつ必要な妥協を行うバランス感覚も欠かせません。主従を間違えなければ、多くのプロジェクトは正しい方向で進むと思います。最初にプロアクティブな対策を考え、プロジェクトのリソース(開発者のスキル、開発期間、開発コストなど)と要求仕様を考慮して、最適なバランスで開発を進める事が重要だと考えています。
Webアプリケーションの脆弱性はWebアプリケーションので対処するべきで、対策が取れるまでサイトを閉鎖するのがセキュリティ対策だけを考慮すれば最良であることは明らかです。対策が行われるまでサイトを閉鎖する事は現実的ではありません。WAFによる保護も必要となるでしょう。しかし、WAF導入等の対策はWebシステムの様に管理された環境下でのシステム開発では受動的な対策と言えます。
# 立場や環境が異なればWAFも能動的な対策と言えます。
# 私は基本的に「開発者」としての立場からセキュリティ
# 対策を見ています。
# 運用担当者の立場から見れば、WAFは能動的な対策と言え
# るでしょう。
私がWAFに関して危惧しているのは、FirewallやSSLによるセキュリティ対策が万能であるかのように誤解された事が、WAFでまた再現する事です。