なぜセキュリティ対策の区別が異なるのか?長年疑問だったのですが、その理由の一つが判りました。
以下は、本質的には似たような入力確認である「WAFはセキュリティ対策」で「入力バリデーションはセキュリティ対策ではない」のか?と質問した時のツイートです。
@yohgaki どちらもセキュリティ上効果がありますが、WAFはセキュリティを主目的として、というよりセキュリティのためだけに導入するのに対して、バリデーションはセキュリティが *主目的ではなく* 元々実施すべきものだという主張です
— 徳丸 浩 (@ockeghem) February 6, 2015
どうも「目的」がセキュリティ対策であるか否か、の基準のようです。「セキュリティ対策の定義」が曖昧という問題もありますが、ここでは省略します。
セキュリティ対策の評価方法 – 標準編
まず言葉の定義ですが、セキュリティ対策の定義についてはこちらをご覧ください。
標準的なセキュリティ対策の評価では、セキュリティ対策は
- 対策の導入コスト(必要なリソース)
- 対策導入後の効果(結果)
この2つで「セキュリティ対策」を評価します。どのセキュリティ対策を導入するか?には定量化を行います。定量化方法には複数の手法がありますが、厳密に定量化を行わないでリストアップするだけでも適切な対策を選択できることが多いです。
どういったモノをセキュリティ対策として評価するか、も簡単です。
- リスクを変化させるモノは全てセキュリティ対策として評価
リスクの変化は「結果」なので、どのような結果を生むか証明/確認/推測できます。この為、見過すことはあっても、特定の施策が「リスク変化」を生ずるかの評価は誰が評価してもほぼ変ることはありません。
入力バリデーションの例
入力バリデーションを行う場合:
- 導入コスト
- (コスト追加)アプリケーションへのバリデーションコードの追加と管理
- 導入結果
入力バリデーションを行わない場合:
- 導入コスト
- (コスト削減)アプリケーションへのバリデーションコードの省略
- (コスト増加)バリデーションを追加しない事により発生するCWE増加に対する緩和策の追加(コード検査コスト増加、メンテナンス時のセキュリティテストコスト増加)
- 導入結果
※ CWE番号の出典:SANS TOP 25 Monster Mitigations #1
これらを客観的に判断し、他のセキュリティ対策の導入と比較し、その対策を採用するかどうかを決定するというプロセスになります。
どのような仕様をセキュリティ対策として採用するか?には標準化も行われており、ISO 15408やISO 18045などもあります。Webアプリのような比較的カジュアルなアプリの場合、これらの標準化手法を使うことはほぼないと思いますが、脆弱性評価基準やプロセス自体は参考になります。
コスト効果の高い仕様を優先して「セキュリティ対策」として導入することを決定し、「セキュリティ対策」の仕様/仕組みについてはセキュリティマネジメントの対象として管理します。標準ではこれら「セキュリティ対策」の定期的な再評価を求めており、環境が変わった場合(例えば、2要素認証導入の必要性増加など)にはあらたな「セキュリティ対策」を採用したり、効果が低くなった「セキュリティ対策」を非採用とします。
個々の要素の評価に主観が入りますが、特定の仕様が「セキュリティ対策」であるかどうか?に主観が入り込む余地はあまりありません。リスクを変化させる仕様は全て「セキュリティ対策」として評価され管理されます。つまりセキュリティ対策の評価が属人化しずらいシステマティックなプロセスになります。
このプロセスで「セキュリティ対策」として採用されなかった物も、単に採用されなかっただけで「セキュリティ対策」であることは変わりません。例えば、2要素認証をセキュリティ対策として採用していないサービスは多いです。2要素認証は採用していない将来のセキュリティ対策として管理、採用後はパスワードのみのセキュリティ対策は非推奨のセキュリティ対策として管理します。
かなりざっくりとした説明ですがこれを知っているだけでも「セキュリティ対策」としてどのような仕様が管理され、どのように適切に管理するのか、概要は理解できると思います。
SANS TOP 25の編集にどのような評価プロセスがあるのかは知りませんが、ここで解説したようなプロセスを経て順位が付けされているはずです。因みに、入力バリデーションは第一位のセキュリティ対策です。
セキュリティ対策の評価方法 – 徳丸さん流
徳丸さん流のセキュリティ対策の評価では「目的」がセキュリティ対策として採用するかどうか、の基準になるようです。
また「目的」が「セキュリティ対策」であるかどうかの判断には「リスクの変化」は関係ないようです。もし「リスク変化」を評価する要素があるならSANS TOP 25 第一位のセキュリティ対策を「入力バリデーションはセキュリティ対策ではなく、仕様として当たり前に実装する」といった評価になりません。特定仕様の「目的」はそれを設定する人の価値観により決定されます。つまり人によって「セキュリティ対策」かどうかが変わります。徳丸さん自身も私の記事を読んで
いや、まさに、エスケープやプリペアードクエリの利用だって「セキュリティ対策」ではないでしょう。怠ったら脆弱性というだけで、元々必要な処理です。
http://tumblr.tokumaru.org/post/57032762801
と「目的」が変わると、一般に「セキュリティ対策」とされるモノであってもセキュリティ対策でなくなる、としています。
このようなプロセスにはセキュリティ対策の客観的/定量的な評価がありません。個人の主観によってセキュリティ対策が変化し、リスク評価も管理もないのでマネジメントできません。「目的」を設定した人以外には、何がセキュリティ対策で、何がセキュリティ対策でないのか、理解することもできません。
この結果、「セキュリティ対策とは何が何だかよく分からない」と私も良く耳にする混乱した状況になります。
個人の感覚/主観だけが頼りで、標準のような「リスクを変化させるモノ」に対する評価手法・プロセスも無く、管理手法もないので、何が何だか解らなくなるでしょう。
とても属人的でシステム性がなく、一貫性もないのでセキュリティマネジメントを行うには問題のある手法です。
もし「リスクを変化させるモノを評価/管理」する手法を追加すると、標準の手法とあまり変わらなくなるでしょう。しかし、「目的」が最優先事項のようなので標準的プロセスに比べ主観による漏れが発生しやすくなります。このため、標準的の手法をそのまま採用する方が良い、となります。
まとめ
基準のない個人の「主観」によって「セキュリティ対策」が変化する場合、
- セキュリティ対策とは何が何だかよく分からない
という結果を生むことは経験則で十分に分かっている方も多いのではないでしょうか?
膨大な資料を作って標準的なプロセスを実行する必要がないプロジェクトが多いでしょう。自分の頭の中、グループでのブレインストーミングなどで標準的プロセスを採用し「セキュリティ対策」を決めるだけでも「セキュリティ対策とは何が何だかよく分らない」を無くしていく事ができます。一度行なえば、次からは前回の結果をテンプレートとして利用することも可能です。
重要なことなのでもう一度
- リスクを変化させるモノは全て「セキュリティ対策」
- セキュリティ対策の評価は「コスト」と「結果」(効果)で決める
- セキュリティ対策には「採用した対策」と「採用しなかった対策」がある
- セキュリティ対策は定期的に再評価
標準通りにシステマティックなセキュリティ管理を取り入れると大変すぎてとてもできない、場合も多いです。しかし、標準手法のエッセンスを用いてセキュリティ管理をするだけでも、随分明解になり管理しやすくなります。
標準的なセキュリティ管理は前近代的/属人的なセキュリティ管理より効率も良く、明解で、簡単です。
短くまとめたで、標準プロセスのこの部分がおかしい、分かりづらい、と気になった方はコメントを頂けると助かります。
追記:
必要なセキュリティ対策を知るには脆弱性カタログやセキュリティガイドラインが便利です。使い易い物にはCWE、CAPEC、OWASP、SANS、ISO 27000などがありますが日本政府のガイドラインなども参考になります。Webアプリなら取り敢えずOWASP TOP 10とSANS TOP 25から始めると良いです。
短くし過ぎたのでもう少し説明します。本来はもう少し踏み込んで「残存リスク」の評価とその対応までします。例えば、SQLインジェクションなら
- プリペアードクエリ
- 対応リスク:SQLパラメータ(リテラル)のセキュリティ処理
- 残存リスク:SQL語句の埋め込み(対応策:バリデーション)、SQL識別子(対応策:識別子エスケープ)
などとします。対応策の種別も区別すると解りやすいです。例えば、入力バリデーションなら”多層防御”、プリペアードクエリなら”対策”、といった感じです。Webアプリのことだけ考えるなら、対応すべき脆弱性は決まっているので、OWASPなどから脆弱性を拾い、自分が使っている環境(言語、フレームワーク、OS、Webサーバー)での対応策を見つけ、上記のリスク分析をします。
それぞれのリスク対応策は利用するモノの仕様を参照して、的確/正確な処理を確認します。言語、フレームワーク、OS、RDBMS、その他全ての入出力先の入出力仕様を確認します。例えば、SQL識別子のエスケープはMySQLとPostgreSQLでは異なります。SQLiteを利用している場合、他の一般的なRDBMSとは異るのでプリペアードクエリを使っていてもセキュリティリスクがあります。
こうやってセキュリティ対策を評価/選択していけば漏れがなくなり、体系的なセキュリティを実施できます。このようにセキュリティを構築すればプリペーアドクエリで防げないSQLiteでのセキュリティ問題も「自分で考え防ぐ」ことができるようになります。
入力バリデーションはセキュリティ対策の基本、SQLiteデータ型の仕様とセキュリティ問題、SQL識別子のエスケープ、いまさら聞けないWebアプリセキュリティの基本ルールなどに書いているよう、体系的なセキュリティの構築には「入力」と「出力」の仕様にこだわる必要性があります。私は一貫して「入力」と「出力」の仕様にこだわるようにと主張しています。
プログラムのロジック「処理」のセキュリティ問題に比べ、「入力」と「出力」のセキュリティ問題の方が遥かに数が多く、確実な入力と出力の管理により「処理」のセキュリティ問題も緩和されることが多いからです。「入力」と「出力」の仕様にこだわると、自然に体系的なセキュリティを自分で考え構築できるようになるからです。