CERTは米カーネギーメロン大学に設置されたコンピュータセキュリティ対策を行う老舗の組織です。CERTが設立される前もセキュリティが無視されていたのではありませんが、CERT設立後と前ではコンピュータセキュリティ、特にソフトウェアセキュリティに対する考え方が大きく変わりました。詳しくはセキュアプログラミング(防御的プログラミング)の歴史をざっと振り返るを参照してください。
CERTはSecure Coding Standardsとして
- SEI CERT C Coding Standard
- CERT C++ Coding Standard
- AndroidTM Secure Coding Standard
- SEI CERT Oracle Coding Standard for Java
- SEI CERT Perl Coding Standard
を公開しています。その中でもセキュアコーディング(セキュアプログラミング/防御的プログラミング)で最も重要なトップ10をTop 10 Secure Coding Practicesとしてまとめています。
日本語訳が無いようなので資料として利用できるよう私訳しておきます。
(追記:IPAのセキュアコーディングガイドは入力対策が出鱈目でした。 2017年からやっとIPAがCERT Secure Coding Practicesをセキュアコーディングの”原則”として紹介するようになりました。CERT版では出力対策を7番目に記載しています。IPAは順序を変えて2番目にしています。トップ10の原則とする際に順序を入れ替えるのは混乱の元です。オリジナルの順序のままにすべきだと思います。順序を変えると外国人とコミュニケーションが取れなくなります。)
よく勘違いされているので書いておきます。入力対策と出力対策は”独立したセキュリティ対策”です。間違えないようにしましょう。
入力バリデーションが第1位の対策であるのは科学的/論理的/原理的な理由が根拠となっています。最も重要な対策ですが、よく誤解されています。
参考:
- エンジニア必須の概念 – 契約による設計と信頼境界線
- OWASP Secure Coding Practices – Quick Reference Guide
- 開発者は必修、SANS TOP 25の怪物的なセキュリティ対策
- セキュアプログラミングの7つ習慣
CERT Top 10 セキュアコーディングプラクティス
第1位 入力をバリデーションする
全ての信頼できないデータソースからの入力をバリデーションする。適切な入力バリデーションは非常に多くのソフトウェア脆弱性を排除できる。ほぼ全ての外部データソースに用心が必要である。これらにはコマンドライン引数、ネットワークインターフェース、環境変数やユーザーが制御可能なファイルなどが含まれる。
(訳注: 2000年から国際情報セキュリティ標準 – ISO 17799/27000、にセキュアプログラミング技術の重要技術として入力バリデーションの実装/管理方法が記載されていた。2013年の改訂でセキュアプログラミング技術は標準化され普及したので”セキュアプログラミング技術を採用する”とする簡潔な記述に更新された。)
第2位 コンパイラの警告に用心する
コードはコンパイラが利用可能な最も高い警告レベルでコンパイルし、コードを修正して警告を排除する。他のセキュリティ問題を発見、排除するために静的/動的な分析ツールを利用する。
第3位 セキュリティポリシーの為に構成/設計する
ソフトウェアの構造と設計はソフトウェアがセキュリティポリシーを実装/強制するよう作る。例えば、システムが異る権限を異る場合に必要とするなら、システムをそれぞれ適切な権限で動作する独立したサブシステムに分離し通信させることを検討する。
第4位 簡易にする
可能な限り設計を簡単かつ小くする。複雑な設計はエラー発生の可能性を劇的に増やし、セキュリティ対策もより複雑化する。
第5位 デフォルトで拒否する
アクセスを許可することを基本とし、排除は行わない。これは、デフォルトでアクセスを拒否し、保護設定でどのような条件下でアクセスを許可するか識別することを意味する。
(訳注:一言で言うと、ホワイトリストを使いなさい、です)
第6位 最小権限の原則を支持する
全てのプロセスは仕事を完遂するために必要とされる最小限の権限で実行する。あらゆる権限昇格は最小限の期間に留める。このアプローチは攻撃者が昇格した権限で任意コードを実行する機会を最小限に留める。
第7位 他のシステムに送信するデータを無害化する
コマンドシェル、リレーショナルデータベースや商用製品コンポーネントなどの複雑なシステムへの渡すデータは全て無害化する。攻撃者はこれらのコンポーネントに対してSQL、コマンドやその他のインジェクション攻撃を用い、本来利用してない機能を実行できることがある。これらは入力バリデーションの問題であるとは限らない。これは複雑なシステム機能の呼び出しがどのコンテクストで呼び出されたか入力バリデーションでは判別できないからである。これらの複雑なシステムを呼び出す側は出力コンテクストを判別できるので、データの無害化はサブシステムを呼び出す前の処理が責任を持つ。
(訳注:入力対策と出力対策は独立した対策だが、90年代までの古いプログラミング原則である”重複した同じ処理は作らない”を今でも原則だと勘違いしているケースが少なくない。)
第8位 縦深防御を実践する
リスクは複数の防御的戦略によって管理する。これは1つの防御層が不適切だったとしても、他の防御層がセキュリティ問題が攻撃可能な脆弱性なることを防いだり、成功した攻撃の結果を緩和できるからである。例えば、セキュアプログラミング技術とセキュア実行環境の組み合わせは開発時にコード内に残った脆弱性を運用環境で攻撃される可能性を軽減できる。
(訳注:縦深防御とは多層防御/多重のセキュリティとも呼ばれています)
第9位 効果的な品質保証テクニックを利用する
良い品質保証テクニックは脆弱性を識別/排除するために効果的である。ファジングテスト、侵入テストおよびソースコード検査、これら全ては効果的な品質保証プログラムの共通要素である。独立したセキュリティレビューはよりセキュアなシステムを可能にする。外部のレビューワーは、例えば無効な仮定の発見と修正など、独立した観点を持ち込む。
第10位 セキュアコーディング標準を採用する
利用する開発言語とプラットフォーム用のセキュアコーディング標準を開発/適用する。
(訳注:”セキュアコーディング標準”はただ利用するだけのモノではない。CERTがCやJava用に作っているいるようなセキュアコーディング標準を自分の開発環境/開発標準に合わせて作る。)
ボーナスセキュアコーディングプラクティス
1. セキュリティ要求を定義する
アプリケーション開発ライフサイクルの初期段階でセキュリティ要求を識別し文書化する。その後の開発成果物はこれらの要求を遵守しているか評価する。セキュリティ要求が定義されていない場合、開発成果物のシステムの安全性が効果的に評価できない。
2. 脅威をモデル化する
ソフトウェアが対象となる潜在的脅威に対して脅威のモデル化を行う。脅威のモデル化は重要な資源およびアプリケーションの機能の識別、それぞれの資源と機能に対する脅威の識別と分類、リスクの順位づけによる脅威の評価が含まれる。その後、脅威の緩和策戦略を実装する設計、コードとテストケースを構築する。
ボーナス写真
訳注:これは元サイトでご覧ください。脅威を識別していない駐車管理システムの写真です。
リファレンス
[Saltzer 74] Saltzer, J. H. “Protection and the Control of Information Sharing in Multics.” Communications of the ACM 17, 7 (July 1974): 388-402.
[Saltzer 75] Saltzer, J. H. & Schroeder, M. D. “The Protection of Information in Computer Systems.” Proceedings of the IEEE 63, 9 (September 1975), 1278-1308.
[Seacord 05] Seacord, R. Secure Coding in C and C++. Upper Saddle River, NJ: Addison-Wesley, 2006 (ISBN 0321335724).
[Swiderski 04] Swiderski, F. & Snyder, W. Threat Modeling. Redmond, WA: Microsoft Press, 2004.
Leave a Comment