SANS TOP 25 の解説はもっと後で行うつもりでした。しかし、現在のアプリケーション開発者向け教育に対する疑念のエントリへの反響が大きいようなので書くことにしました。
やるべきセキュリティ対策には優先順位があります。効果が大きい対策から行うべきです。セキュリティ対策は全体的に行うべきものですが、最も効果的な対策を除いて対策を行うようでは全体的な対策など行えません。
CWE/SANS TOP 25とは?
SANS TOP 25の正式名称はCWE/SANS TOP 25 Most Dangerous Software Errorsです。名前の通り最も危険なソフトウェア脆弱性のトップ25を挙げ、その対策を解説したセキュリティ対策のガイドラインです。SANS TOP 25は米国のセキュリティ教育・認証・研究機関であるSANSが不定期に発表しています。SANSの人達は米国の国防総省のセキュリティ対策やコンピュータセキュリティ標準などまとめたセキュリティ基準など含む技術標準策定を取りまとめる米国政府機関のNISTに関わっています。日本のIPAもNIST文書の一部を日本語訳で公開しています。
CWE(Common Weakness Enumiration)とはCVE(Common Vulnerability and Exposure)を管理している米政府の外郭団体であるMITRE社が管理してる脆弱性カタログです。脆弱性を一意に識別するCVE番号は脆弱性情報と一緒に公開されているので知っている方も多いと思います。CWE/SANS TOP 25のCWEとはMITRE社が管理するCWEカタログを指しています。
TOP 25の脆弱性の一番が最も重要なセキュリティ対策であると思われるかも知れません。しかし、そうではありません。
CWE/SANS TOP 25のMonster Mitigationとは?
SANS TOP 25はCWEカタログの中から25の最も危険ソフトウェア脆弱性を抽出し解説していますが、それとは別にMonster Mitigations(怪物的なセキュリティ対策)として5の緩和策(Mitigations)と4つの一般的対策(General Protection)を挙げています。
A Monster Mitigation Matrix is also available to show how these mitigations apply to weaknesses in the Top 25.
ID Description M1 Establish and maintain control over all of your inputs. M2 Establish and maintain control over all of your outputs. M3 Lock down your environment. M4 Assume that external components can be subverted, and your code can be read by anyone. M5 Use industry-accepted security features instead of inventing your own. GP1 (general) Use libraries and frameworks that make it easier to avoid introducing weaknesses. GP2 (general) Integrate security into the entire software development lifecycle. GP3 (general) Use a broad mix of methods to comprehensively find and prevent weaknesses. GP4 (general) Allow locked-down clients to interact with your software. See the Monster Mitigation Matrix that maps these mitigations to Top 25 weaknesses.
トップ25が危険な脆弱性の順序であり、この順序は効果的な対策の順序になっています。
これを解説する前に、セキュリティ対策とは緩和策である、という定義を理解しなければなりません。セキュリティ対策の定義から、セキュリティ対策は「完璧」である必要はありません。
セキュリティ対策とは?
セキュリティ対策はリスクを十分に軽減する緩和策であれば有効です。例えば、現在一般的に利用されている暗号に完璧な暗号はありません。論理的には総当り方式で鍵を解読できます。しかし、実用的な時間内で解読する事が不可能である暗号方式であれば「十分な緩和策」であるとし利用します。
Monster Mitigationを「怪物的な緩和策」と訳さず、「怪物的なセキュリティ対策」と訳しているのは「Security対策=緩和策」1である事に基づく意訳です。
セキュリティ対策は「こうでなければならない」という物はあまりありません。様々な対策があり、それぞれ効果が違います。ニーズや現状に合わせて「有効」(効果的・現実的)な対策を採用すれば良いです。つまり、このセキュリティ対策は「これをやれば必要ない」からダメ・無用だとする議論にはあまり意味はなく、この対策は論理的・現実的に有効である、この対策は論理的・現実的な欠点や欠陥がある、とする議論をすべきです。
セキュリティ対策に欠点や欠陥があるからといって利用してはならない、セキュリティ対策ではない、という結論にはセキュリティの定義からなることはありません。有効な対策であれば十分です。もし欠点や欠陥のある劣る対策を使ってはならないのであれば、今直ぐユーザー名とパスワードのみによる認証は止めなければなりません。
「有効」の定義は時代と共に変わります。昔のキャッシュカードには暗証番号が記録されていました。現代の基準ではとても有効とは考えられませんが、当時はこれでも有効なセキュリティ対策でした。「有効」の定義は流動的であることにも留意してください。ユーザー名とパスワードのみによる認証が「有効」でない、とされるのはそう遠い未来の話ではないと思います。
前置きが長くなりましたが、最も有効なセキュリティ対策の第1位と第2位を紹介します。
M1: Establish and maintain control over all of your inputs.
入力制御、つまり入力バリデーションが怪物的なセキュリティ対策の第1位です。全ての入力に対する制御を確立しなさい、としています。セキュリティ対策で最も有効な対策は入力バリデーションであり、全ての入力を
- 長さ
- 形式
- 過不足
- 関係性
- ビジネスルール
でバリデーションする事としています。
全ての入力はホワイトリスト型のチェックによるバリデーションを行い、バリデーションルールに違反するデータは受け付けてはならず、拒否できない場合は安全な値に変換するようにとしています。
どこから「信用できない入力が入ってくるのか」理解する事も求めています。入力のバリデーションを「アプリケーションの入り口」で行うことは重要です。セキュリティ対策の基本に境界防御があります。バリデーションにはビジネスロジックで行うしか無い物もありますが、入力処理でバリデーションできる物は入力処理時にバリデーションを行うのが最も合理的かつ効果的です。MVCモデルなら入力を受け付けるコントローラーでバリデーションを行うと良いでしょう。関係性やビジネスルールなど、モデルでバリデーションすべき物はモデルで行います。
全ての入力を境界となる「入力処理」でバリデーションすると、ソースコード検査でアプリケーション安全性を保証することが容易になるメリットもあります。
入力バリデーションによる境界防御だけで全ての問題を解決することはできませんが、境界防御を最重視しないセキュリティ対策は論理的・現実的にあり得ません。私もSANSのセキュリティ専門家と同じく入力バリデーションが最も重要なセキュリティ対策と考えています。
バリデーションにはデータバリデーションとロジックバリデーションの2種類あります。OWASP Source Code Review Guideでも2種類のバリデーションが実施されているか、レビューするようにと記載されています。
データバリデーションは入力処理(MVCアーキテクチャーならコントローラー)、ロジックバリデーションはプログラムのロジック(MVCアーキテクチャーならモデル)で行います。よく勘違いされるようななので注意してください。
M2: Establish and maintain control over all of your outputs.
出力制御、つまり安全に出力する対策が怪物的なセキュリティ対策の第2位です。全ての出力を安全に出力する事を求めています。
全ての出力を安全に出力するには、全ての出力先の入力仕様を正しく理解する必要があります。入力仕様を理解し正確に出力しないとコンピュータが誤作動し、攻撃者の不正な命令を実行してしまう場合があります。
まず出力先のが誤作動しない入力仕様を知ることが重要です。誤作動しない出力を知る最善の方法は出力先の誤作動を起こさせないエスケープ仕様を知ることです。もし、データ(パラメーター)と命令を分離する仕組みがある場合、これらを利用すべきとしています。その方法には、開発者が独自に実装した仕組みを利用するのではなく、用意されたクオーティング(エスケープ)、エンコーディング、自動バリデーションを利用すべきとしています。
複数のエンコーディングが必要な場合には特に注意すべきとしています。WebアプリならHTMLパーサーとJavaScriptパーサーの両方が解釈するHTML埋め込みJavaScriptなどが相当します。
出力制御が2番目となっているのは入力制御と同じく、境界防御を最重視しないセキュリティ対策は論理的・現実的あり得えないからです。境界(アプリケーション)を越える出力が安全でなければ、出力先のシステムが誤作動します。セキュリティの基本から入力制御の次に重要な対策として出力制御があるべきです。
その他の対策
怪物的なセキュリティ対策とする対策は、アプリケーションのセキュリティ対策として全て重要な対策です。ここでは解説を省略しますが、SAN TOP 25の全ての怪物的なセキュリティ対策とTOP 25の問題を理解する事をお薦めします。
セキュリティ対策であるべき議論
一定以上の効果(有効性)を持ったセキュリティ対策(緩和策)であれば、セキュリティ対策に「これが正解、他は間違い」という物はあまりありません。セキュリティ対策で議論すべきは
- 有効性(Effectiveness)
- 現実性(Feasibility、Reality)
であると考えています。効果的なセキュリティ対策は有効性のみで判断するものではありません。現実性を伴わないセキュリティ対策では、どんなに理想的な対策であっても採用することはできません。(例:量子暗号)
根本的なアプリケーションセキュリティ対策
根本的なアプリケーションセキュリティ対策はアプリケーションに開発者が脆弱性を作らないようにする事です。開発者がアプリケーションに脆弱性を作らないようにするには、開発者がアプリケーション開発のリスクを認識し、適切なコードを書くように教育するしかありません。
どのような教育が有効で現実的でしょうか?
リスクを認識(TOP 25)させ、適切なアプリケーションを作れるように対策(Monster MitigationsとTOP 25の対策)を教える事が有効です。
アプリケーション開発者が知るべき対策、つまりセキュリティ教育で教えるべき第1位、第2位のセキュリティ対策はこのエントリで紹介した怪物的なセキュリティ対策の第1位と第2位です。その有効性は世界トップのセキュリティ専門家達が認めています。入力・出力の確実な制御に必要となる知識はアプリケーション開発者にとって必須のセキュリティ知識です。ホワイトリスト型の入力バリデーションが必須であること、安全な出力形式を知り確実に安全な方法で出力することは、プロの開発者にとって欠かすことができない基礎知識です。
基礎知識があることを前提とし、特定環境をいかに安全に使うか教育する事は間違いではありません。誤りでないどころか複数のセキュリティガイドラインなどでも推奨されている対策です。
しかし、まだ基礎知識の教育も受けていないにも関わらず、プロの開発者に必須の基礎知識を教えない教育は誤りです。
基礎を押さえていないことによる誤解
原理原則に基づく基礎を理解していないと誤解をしてしまいます。フェイルセーフ対策とデフェンスインデプス(深層防御、多層防御)がよく誤解されるので付け加えます。
フェイルセーフ対策は実行すべきセキュリティ対策が完璧に行われていれば、必要ないことが多いです。しかし、実際のアプリケーションで実行すべきセキュリティ対策が完璧に行われていない(現実性)事はよくあります。実際に不完全なアプリケーションが存在するにも関わらず、「これをやっていれば脆弱にならないから必要ない」とする現実を無視した議論には意味がありません。入力バリデーションは事前のフェイルセーフ対策と言えるセキュリティ対策です。
デフェンスインデプス(境界防御でなく、内部での防御)は境界での防御が不十分だったり、不可能である場合に行う対策です。ディフェンスインデプスは、まず境界での防御を行った上で行います。境界防御を行わずにデフェンスインデプスで対応しているから十分、とするのはセキュアな設計・仕様とは言えません。よくある勘違いは「文字エンコーディングのバリデーション」です。文字エンコーディングのバリデーションは境界防御で実施するのが最も合理的かつ論理的です。
SANS TOP 25は実践的なセキュリティガイドラインとなるように設計されています。基礎的な概念については別途学習・教育する機会が必要だと思います。
まとめ
セキュリティ対策は緩和策であり、数えきれいないアプリケーション仕様の中から安全性を維持する為に必要な対策を抽出した実践すべき仕様です。稀に「入力バリデーションは仕様であるからセキュリティ対策ではない」とする議論を見かけますが、これは論理的に正しくありません。
セキュリティ対策を議論する場合、その対策の有効性と現実性を議論しなければなりません。誰がどう言っていたなど、それ以外の議論はおまけと言える議論です。全体的な有効性と現実性を無視した議論を見かける事がありますが、有意義な議論にするには有効性と現実性を考慮する事が欠かせません。
このエントリでは既に確立されている基本的概念・対策の有効性や現実性の解説は省略しています。これらの解説が目的ではないからです。もしここに書かれている事の有効性や現実性に疑義を感じた方は、論理的になぜ有効性や現実性を疑うのか解説の上で質問頂けると助かります。
SANS TOP 25は脆弱性評価基準や現実の脆弱性を考慮し体系的・論理的にまとめ、対処すべきトップ25の脆弱性、実践すべきセキュリティ対策を解説した文書です。全てのアプリケーション開発者にお勧めできます。全ての開発者に文書全体を理解し実践して頂きたいと願っています。
最後に、アプリケーションセキュリティの根本的対策である教育には幾つかの種類がある事を理解してください。「基礎教育」と「実践教育」では内容が異なります。「プロを対象」とした教育と「素人を対象」とした教育では内容が異なります。現在のセキュリティ教育は「プロを育てる基礎教育」として問題があるのでは?と感じています。
参考: 今のアプリケーション対策は出力対策偏重の構造です。これは非効率でリスクを生み、論理的に間違ったセキュリティ構造です。
- ISO 27000の定義に基づくと、緩和策もセキュリティ対策です。ITに関わる人ならISO 27000の定義を利用すべきでしょう。特にセキュリティ専門家なら。 ↩