このブログを継続的に読んでいる方なら私が「個々のセキュリティ脆弱性対策も重要だが、基本的考え方や概念はより重要である」と考えていることがわかると思います。「個々の脆弱性対策だけやれば良い」とする議論がありますが、これには色々な欠陥があります。このため、「個々の脆弱性対策だけやる」では効果的なセキュリティマネジメントができません。つまり、より危険なセキュリティになってしまいます。
追記:このエントリだけではなぜマネジメントが大切なのかは伝わらないと思うので、容易に導入できるセキュア開発メソドロジー – OpenSAMM を書きました。こちらも参照ください。
「個々の脆弱性性対策だけやれば良い」の落とし穴
これから紹介する落とし穴は専門家でも落ちてしまった落とし穴です。
ブラックリスト編
「個々の脆弱性対策だけやれば良い」と考えていると、セキュリティ対策の基本であるホワイトリスト型セキュリティを否定してまう場合があります。
ホワイトリスト方式の優位は神話はその典型例です。個々の脆弱性だけに着目すると「対応しようとしているリスク」にのみに焦点があたり、そのリスクを除去/緩和する対策だけに集中してしまう、という誤りをしてしまいます。
ブラックリスト思考は目の前に見えているリスクのみを排除し、気付いていないリスク/隠れたリスクの排除ができません。このため、あらゆるセキュリティガイド/標準は「ホワイトリスト型で対策する」ことを推奨しています。
入力バリデーション編
「個々の脆弱性対策だけやれば良い」と考えていると、個別の脆弱性対策にならないモノはセキュリティ対策ではない、セキュリティ対策としてどうでもよい、といった誤った理解をしてしまいます。
プログラミング原則の1つであるセキュア・防御的プログラミングで先ず第一にすべきとしている「入力バリデーション」です。セキュアなソフトウェアではソフトウェアの”信頼境界線”を越える入力と出力でセキュリティ対策を行います。入力ではホワイトリスト型でバリデーションを行い、出力ではエスケープ(エンコード)/安全なAPIを安全に利用/バリデーションで”完全”にセキュリティを確保します。
参考:
「個々の脆弱性対策だけやれば良い」と考えていると、広範囲な脆弱性に対応/緩和する入力バリデーションをセキュリティ対策ではない、どうでもよい、と勘違いしてしまいます。
ホワイトリスト型の入力バリデーションを行うと想定していなかったリスクにも対応できます。入力バリデーションをセキュリティ対策として導入することにより安全性が向上することは簡単な数式で証明できます。
- 潜在的なリスクの数(仮に1000)
- 出力対策で対応できたリスク(仮に95%)
- 入力バリデーションで対応できたリスク(仮に90%)
とした場合、
- 入力バリデーション有り:1000 * 0.05 * 0.10 = 5
- 入力バリデーション無し:1000 * 0.05 = 50
となり、確実にリスクの軽減が可能になります。セキュアプログラミングに於ける目標は「攻撃可能な脆弱性をゼロ」にすることです。セキュリティ対策として入力バリデーションを行うかどうか?考える必要もないほど明白です。
データベースインジェクション対策編
SQLインジェクション対策としてプリペアードクエリが有用ですが、「パラメータに対するインジェクション」つまり個別の脆弱性に対してのみ着目してしまい、他の脆弱性対策を見逃すことが多くなります。
- プリペアードクエリは識別子/SQL語句の分離ができない
- プリペアードクエリではない既存のコードを考えない
- プリペアードクエリは変数の埋め込みを禁止できない
データベース類の出力先はSQLをサポートするRDBMSだけではありません。XML(XPathやXQuery)、LDAPなども出力先です。これらの出力先にはエスケープ機能さえない物や仕組みとしてはエスケープをサポートしていてもAPIが無い物もあります。プリペアードクエリのように命令とパラメータを分離するAPIが無い物もあります。
つまり、一般論としてデータベースへのインジェクション対策を論ずる場合
- エスケープ(エンコード)
- 安全なAPIを安全に使用(安全と言われるAPIでも制限がある場合が多い)
- バリデーション
をセットとして理解すべきですが「プリペアードクエリさえ使っていればOK」と誤った理解になってしまう場合があります。
リスク評価編
「個々の脆弱性対策だけやれば良い」と考えていると、セキュリティ対策で重要なリスク評価を軽視しがちです。上記のデータベース編からもわかるように、特定のリスクにだけ着目して対策すると他のリスクを見落としてしまいます。「個々の脆弱性対策だけやれば良い」は往々にして「この対策だけやれば良い」になってしまいます。
リスクを正しく評価し、残ったリスク、生まれたリスクに対する対策は同時に考えなければなりません。正しいリスク評価は「個々の脆弱性対策だけやれば良い」と考えていると、困難になるようです。
参考:実は標準の方が簡単で明解 – セキュリティ対策の評価方法
マネジメント編
セキュリティ対策は本質的にセキュリティマネジメントです。ITシステムを使う上でどうしても発生してしまうリスクに対する対策を実施しマネジメントするのがITセキュリティ対策です。「個々の脆弱性性対策だけやれば良い」だと、ISO27000などには興味がない、マネジメント不在でも構わない、といった誤りをしてしまいます。
品質管理の専門家や担当者が、ISO9000には興味がない、マネジメント不在でも構わない、といった考え方で品質管理をしてマトモな品質管理が可能になるでしょうか?私はならないと思います。ISO9000には認証制度もありビジネス遂行上さけて通れない場合も多いです。
ISO27000にも認証制度(ISMS)があり、ITセキュリティマネジメントは避けて通れない場合もあり、ISMSを取得しなくてもマネジメントを避けて通るべきではありません。
「個々の脆弱性性対策だけやれば良い」で必要な知識
セキュリティ対策の基本概念を理解せずに「個々の脆弱性対策だけやる」場合は膨大な知識が必要になります。
例えば脆弱性カタログであるCWE(Common Weakness Enumeration)にカテゴリを含めると約1000の脆弱性、攻撃パターンカタログであるCAPEC(Common Attack Pattern Enumeration and Classification)に450以上の攻撃の”共通”パターンが登録されています。”共通”パターンなので個別の具体的なケースは、言語やシステム/ライブラリなどが関連するため、全体としては簡単に数千を越える個別具体的なパターンが必要になります。CWE/CAPECだけでも十分多い量ですが、かなりの知識が必要です。しかも、”共通”カタログであるCWE/CAPECは”全て”の脆弱性/攻撃を網羅していません。※
※ 登録されているモノで、ほとんど全ての脆弱性/攻撃パターンを理解できますが、「これだけやれば良い」というカタログはなく、読み解く能力/知識が必要です。実際に載っていた方が良い、と思えるモノがない場合も少くありません。
全ての開発が熟知するには多過ぎるCWE/CAPECですが、利用しようとした場合、自分の開発環境に合わせないと使い物になりません。CWE/CAPECを自分の環境に合わせて利用する、という作業は「個々の脆弱性性対策だけやれば良い」だけでは不可能です。自分の開発環境の知識はもちろん、セキュア/防御的プログラミング、セキュリティアーキテクチャーなどの基本的知識や考え方が不可欠です。
しかし、セキュリティの基本的な考え方を理解していれば、入出力のセキュリティに関してはCWE/CAPECが無くても自分で的確にリスクを識別し、対応できるようになります。
まとめ
「落とし穴」などには気をつけるとしても「必要な知識」はどうしようもありません。全てのソフトウェア開発において「CWE/CAPEC+開発環境に適用する知識」を持ったセキュリティコンサルタントを雇用できるなら良いのですが、不可能です。現実にはセキュリティコンサルタント不在で開発している現場がほとんどです。
実際の開発現場に於て必要とされる「これだけやれば良い」は限定的なので、ある程度知識がある方がリストを作れば何とかなります。しかし、「セキュリティ対策」が「なんとかなる」で良いでしょうか?
私はセキュア/防御的プログラミング、セキュリティアーキテクチャーなどの基本的知識や考え方を理解した上で「これだけやれば良い」とするリストを作った方がより確実なセキュリティを実現できると考えており、開発者自身でできる※、と思っています。
※ こう思っているので基本的な考え方や概念を強調して紹介しています。
いきなり「開発者全員が自分自身でできる」事は期待していません。これは不可能です。セキュリティ対策以外にも開発者が覚えなければならない事は山程あります。自分自身/自分たちの組織でできるようになるには段階的な成長が必要です。私は比較的容易に導入できるOpenSAMMを推奨しています。
「個々の脆弱性性対策だけやれば良い」の問題は、セキュリティアーキテクチャー、セキュリティの基礎や概念、セキュリティマネジメント、自己解決が欠如していること、ではないでしょうか?
アーキテクチャー、基礎/概念、マネジメントの無いセキュリティ対策で安心できる方はあまり居ないと思います。