何年間も下書きのまま塩漬けになっていたエントリを多少修正して公開します。
プログラミングではホワイトリスティングが基本ではプログラミング/システム開発とセキュリティに対する基本的な考え方をまとめて説明していませんでした。手短にこれらの基本的な考え方・解決策を紹介します。
このエントリでは「アプリケーション開発における根本的なセキュリティ対策」を考えています。
問題を知る
多くのセキュリティ上の問題は複数のシステムがデータ交換う場合に発生します。データ交換を伴わない認証の問題、システムの安定性の問題などもセキュリティ問題です。脆弱性報告されるセキュリティ問題の8割、9割は入出力の問題です。入出力以外、つまりアプリケーションロジックの問題も重要な問題ですがこのエントリでの考察は省略します。省略はしますが紹介するセキュアな開発プロセスを実施すればロジックの問題も回避できるようになります。
データ交換(入力・出力)を行う場合にセキュリティ問題が発生する、を言い換えるとデータを入力と出力時にセキュリティ問題が発生しないようにすればセキュリティ問題は発生しない、ということになります。
実際、プログラミング上のミスが原因であるセキュリティ問題の多くがデータの入出力の取扱いが原因です。
問題の原因
この様な単純ミスが発生する大きな原因は、開発者の認識不足と知識不足です。
一般に開発者が実行効率が良いコードや短いコードを好みます。実行効率が良いコードとはプログラムに余計なチェックを入れず、最小限のチェックでプログラムが”予定したデータ”で実行できるコードです。最小限のチェックを行うコーディングは結果的に短いコードを生成します。短いコードは分かりやすく、メンテナンスを行う際に手間を削減します。このように実行効率が良く、短いコードを好む傾向は必然と言えますが、セキュアなコーディングプラクティスと相反する性質を持っています。
最近ではかなり啓蒙が進み、セキュリティを考慮した設計(アプリ入出力の確実な制御)の重要性が広く認識されはじめています。しかし、安全なシステムを作る視点を欠いた設計アプリケーションも多くあります。先ほどの記述したように実行効率と短いコードを好む傾向を持った開発者により設計・構築されたアプリケーションには、十分な安全性を維持できない設計・コードである傾向があります。
SANS/CWE TOP 25のMonster Mitigation #1と#2は、確実な入力/出力の制御としています。様々レベルでの入力/出力の制御が可能ですが、最も重要な入出力はアプリケーションへの入力とアプリケーションからの出力です。
問題の解決策
複数のセキュリティ標準やガイドラインで「確実な入出力の制御・管理」を要求しているにも関わらず、単純な入出力の制御・管理さえ行われていません。
既に述べたように、このセキュリティ問題は
- 認識不足
- 知識不足
が主な原因です。
開発プロセスがセキュアであるようにPDCAサイクルで管理している組織は比較的多いと思います。しかし、アプリケーションセキュリティの根本的な対策である開発者への教育・トレーニングをPDCAサイクルで管理している開発会社がどれくらいあるでしょうか?
アプリケーションに脆弱性を作らないようにする根本的な対策とは「開発者が脆弱な設計・設定・コードを書かなくなるようにする」ことです。当たり前の事ですが、これを体系的にマネジメントしている会社は多くありません。
何から始めるべきか
まずはセキュリティポリシーを策定し、PDCAマネジメントで管理しましょう。
セキュリティポリシーは、問題が発生したら対処するようなポリシー、パッチワーク的に対処するようなポリシーでは意味がありません。本題ではないので解説は省略しますが、組織がセキュアな開発プロセスを実施し、自律的に改善できるようなポリシーになっていなければなりません。
PDCA(Plan, Do, Check, Action)は次のような事を実行します。
P: リスクを洗い出し、各リスクを評価し、各リスクに対する対策を決定
D: 各リスクの対策を実行
C: 各リスク対策に問題が無いかチェック
A: 問題に対するアクションを実行
具体的には
P: アプリケーション開発のリスクと対策の洗い出し
- 開発者の認識不足、知識不足 → 教育・トレーニング・ナレッジベース
- 開発時の組み込まれてしまう脆弱なコード → ソースコード/脆弱性検査・セキュア開発プロセス
D: 各リスクに対する対策の実行
- 教育・トレーニングで知識を身に付ける
- ナレッジベースを構築していつでも必要なセキュリティ知識にアクセス可能にする
- ソースコード検査、セキュリティスキャナーなどによる脆弱なコードの検出
C: 各対策の実行状況、実行結果の確認
- 開発者に対するセキュリティクイズの実施
- ナレッジベースの情報が適切・最新であるか確認
- ソースコード検査、セキュリティチェック結果の確認
A: チェック結果から次の実施項目を策定
- 脆弱になってしまった原因の特定
アプリケーション入力値の検証はセキュリティ対策として最大の効果があります(SANS/CWE TOP 25 Monster Mitigation #1)「入力値の検証はセキュリティ対策ではない」などと認識していて安全なアプリケーションが作れるはずがありません。まずこういった誤った認識をなくし、必要な知識を開発者が持てるよう組織的にPDCAサイクルを回す必要があります。
組織的に開発者をサポートするセキュリティ対策は必須
アプリケーション開発において最大のリスクは開発者の認識不足・知識不足であり、開発者の認識不足・知識不足によるセキュリティ問題を軽減するには
- 開発者の教育・トレーニング
- 開発者が作った成果物の検証
- セキュリティ関連のナレッジベース構築
- これらを体系的に行うSAMM(Software Assurance Mutuality Model)などのセキュア開発モデル導入
など「組織的に開発者をサポートするセキュリティ対策」は欠かせません。これらをPDCAサイクルで管理すれば組織的にセキュアな開発体制を構築できます。
セキュリティ知識の習得を開発者個人の努力に任せている場合がほとんどです。しかし、脆弱なコード・アプリを作ってしまった事を個人の責任にしていては何時まで経ってもセキュアなアプリは作れません。組織的に教育・トレーニングを含めたセキュアな開発プロセスを導入することが必要です。
SAMMは成熟度モデルであるため導入が比較的容易です。CMMIに比べるとかなり簡易であり導入しやすくなっています。まだセキュア開発プロセスを導入していない場合、全ての組織・会社にお薦めします。
まとめ
書くべき事が多すぎて書ききれず、中途半端なエントリになってしまった感は否めませんが、取り敢えずまとめます。
Webアプリケーションを安全に作るためには、非常に多くの知識が必要です。しかし、全ての開発者に細々として知識が必要かというとそうでもありません。JavaScript文字列を安全にエスケープするには多くの知識が必要ですが、エスケープ関数が安全であると信頼できる場合は「エスケープが必要な箇所にエスケープ関数を利用する」と知っているだけで十分です。Webアプリケーションの本質(Webアプリセキュリティの基本ルール)を知っていれば「正確なテキスト管理」を行う事が最も効果的なセキュリティ対策であると分かります。Webアプリセキュリティの基本ルールを意識するだけでも、よりセキュアなコードを書けるようになります。
基本ルールを押さえた上で適切にナレッジベースを構築すれば、開発者が知っておくべき知識はそれほど多くなりません。ナレッジベース構築は体系的なセキュア開発プロセスの有無に関わらず直ぐに行えます。
SAMMは多くの開発組織にお薦めできるセキュア開発モデルです。セキュアな開発を行いたいと考えている組織はまずSAMMに取り組むと良いと思います。
組織的・体系的に教育・トレーニング/開発時の各プロセスでのセキュリティチェックを含めたセキュアな開発プロセスを導入する際に協力が必要な場合、弊社にご相談頂ければ支援させて頂きます。