CERT C++を無視する理由はない

CERT C++などのセキュリティコーディング標準を無視していい理由を見つけるのは本当に困難です。この記事では、CERT C++セキュリティ標準について詳しく説明します。

セキュリティは、ソフトウェア開発チーム、特にセーフティクリティカルまたはミッションクリティカルなソフトウェアを担当するチームにとっては、常に唱えられるお題目のようになっています。以前は、多くの場合セキュリティとは開発サイクルの最後の段階で(たいていは侵入テストと修正を繰り返すという悪循環によって)、すでに構築が終わったシステムに追加される「機能」でした。しかし今日の私たちは、セキュリティとは、複数の研究プログラムや標準に裏付けられた確固としたエンジニアリング分野であることを知っています。

システムを設計から安全なものにしたいなら、開発プロセスの最初の段階から始めて、作成されたコードのすべての行がセキュリティのベストプラクティスに従っていることを確認する必要があります。C++で開発するチームにとって、頼るべき最良の選択肢の1つはSEI CERT C++標準です。Parasoft C/C++testは、この標準を包括的にサポートする唯一のツールであり、CおよびC++コードの市場で最も完全なセキュリティテストおよびコンプライアンスソリューションです。

数で見るCERT C++コーディングガイドライン

SEI CERT C++標準には、セキュアコーディングプラクティスを推進し、脆弱なコードを排除するためのルールが集められています。標準は、特定のトピック分野ごとにルールを分類した11の章で構成されています。CERT Cとは異なり、CERT C++コーディング標準にはルールしかなく、推奨事項はありません(推奨事項については今後のレビューと開発が待たれます)。SEI CERT C++はCERT C標準に依存しており、C++にもあてはまるCERT C ルールのサブセットを包含しています。現時点では(CERTは変化の途上にある標準であることを忘れないでください)、83個のCERT C++ルールとCERT Cから継承された80個のルールがあります。標準の概要を次の表に示します。

Parasoft C/C++testは、バージョン10.4.1で CERT Cコーディングガイドラインを完全にサポートし、CERT C++コーディングガイドラインは83個のルールのうち79個をサポートしています。テストコンフィギュレーション(“ SEI CERT C++ Rules”)では、CERT C++オリジナルのルールセットおよびC++に適用可能なCERT Cのルールのチェックが有効にされており、これはまさにCERTがC++コードのセキュリティ確保のために定義したとおりです。C++への移行を計画しているチームを含め、CおよびC++の両方で開発を行っている組織は、単一のツールによる一貫したレポート機能を利用できます。

また、CERT CおよびC++専用のコンプライアンスレポートを利用して持続可能なコンプライアンスプロセスを構築できます。レポート拡張機能を使用すると、コンプライアンスプロセスを動的に把握できるほか、CERTのリスク評価フレームワークに従って優先順位付けされた違反を参照することが可能です。

CERTは、次の3つの要因について、すべての違反にスコアを付けます。

  • 重大度
  • 可能性
  • 修正コスト

優先順位は、これら3つの要素の積として計算され、レベル(L1、L2、およびL3)に分けられます。   L1は、可能性が高く修正コストが低い、重大度の高い違反を表します。重大だが修正が困難ではない問題であるため、最も積極的に修正するべきものです。CERTのスコアリングフレームワークを使用すると、労力を集中させ、与えられた時間を最大限に活用するのに非常に役立ちます。

Parasoftのレポートフレームワークは、ウィジェット、違反エクスプローラー、そしてコンプライアンスプロセスにおいて向かうべき方向を素早く示すリスクスコアリングフレームワークを提供するほか、コード監査に適したコンプライアンスレポートを自動生成することでも時間を節約します。開発プロセスに関してより厳格な形式を求める組織にとっては、これは非常に歓迎される機能です。CERTコンプライアンスレポートフレームワーク については、Arthurの関連ブログを参照してください 。

CERT C++の利点

C++は優れた言語です。最新のオブジェクト指向言語の多くの機能を備え、高度なオブジェクト指向デザインパターンを使用して複雑なシステムを設計することができるいっぽうで、アクセスが正しいかどうかをチェックしなくてもポインターによってメモリに直接アクセスできるため、高い効率性を実現することもできます。

もちろん、これらの利点には代償があります。C++を使用する場合、経験豊富なソフトウェア開発者であっても、特にメモリのアクセスおよび管理の問題によって、脆弱なコードを作成してしまう場合があります。バッファオーバーフロー、ダングリング参照の使用、整数オーバーフローはすべて未定義の動作につながる可能性があり、これはさまざまな方法で悪用される可能性があります。攻撃者はこれらを利用してアークインジェクション (プロセスメモリに存在する意図されたものとは異なるコードに悪意を持って制御を移すこと)またはコードインジェクション (実行中のシステムのメモリにコードを注入すること)を試み、侵害されたプログラムの権限、または最悪の場合はカーネルアクセスレベルでシステムの制御を乗っ取ろうとします。このように制御が奪われると、損失は壊滅的なものになる可能性があります。 

それでは、攻撃者がシステムに侵入するのをどのように防げばよいのでしょうか?すでにあるコードを対象として、考えられるすべてのセキュリティ侵害を推測することは不可能です。現在C/C++プログラマーが取りうる最善の選択肢は、最初からセキュリティ侵害の原因となることが証明されている特定の構文がないコードを作成することです。

それでは、簡単な例を見てみましょう。以下のソースコードは、CERT C ++標準から引用したものです(ルールEXP61-CPP)。

auto g() {

int i = 12;

return [&] {

i = 100;   // Problem

return i;

};

}

void f() {

int j = g()();

}

この例では、関数 g()はラムダを返します。このラムダは、自動ローカル変数 “i”を参照によって暗黙的に取得します。このよくないコードは、g() の呼び出しからラムダが返されるとき、少なくとも1つのセキュリティ脆弱性を発生させます ―― ラムダがキャプチャした参照は、生存期間が終了している変数を参照することになります。結果として、f() でラムダが実行されるとき、ラムダ内のダングリング参照を使用すると未定義の振る舞いになります。この未定義の動作は、プログラムの制御を奪うために悪用される可能性があります。g 関数の有効期間内に i によって占有されていたメモリはすでに解放されています。おそらくこのスタックのチャンクは他の目的、たとえば関数呼び出しからの戻りアドレスとしてすでに再利用されており、上書きされると、任意のコードを実行するのに利用される可能性があります。

この脆弱性は、ルール EXP61-CPP 「ラムダ オブジェクトは参照キャプチャされたオブジェクトよりも生存期間が長くてはいけない」で検出可能です。そのため、CERT C++に準拠したソースコードでは、この問題は発生しません。

CERT C++には、ほかにも、潜在的な問題を検出しセキュアコーディングプラクティスを推進するのに役立つルールが多く含まれています。セキュリティコーディングガイドラインは、一貫して使用した場合、ソースコードを強化するのに役立ち、システム全体のセキュリティを確保する最も効果的な戦略となります。そして最近では、CERT C++などのセキュリティコーディング標準に従わないことを正当化するのは本当に困難です。

この記事は、開発元Parasoft社 Blog 「There’s No Good Reason to Ignore CERT C++」2018年12月20日の翻訳記事です。)

静的解析・単体テストツール C++test

C++testは、静的解析(コーディング規約チェック/フロー解析)、単体テスト、カバレッジの計測、実行時メモリエラー検出、 効率的な運用や規格順守を補助する機能などを搭載したC言語/C++言語対応のオールインワンテストツールです。
MISRA C/C++、CERT C/C++コーディングスタンダード、AUTOSAR C++14コーディングガイドラインなどで定められた規約に基づくコーディングの支援や、単体テストやアプリケーション実行時に自動的にカバレッジを計測するなど、さまざまな要件に対応し、ソフトウェアの品質向上とテスト工数の大幅削減をサポートします。
静的解析・単体テストツールC++test
静的解析・単体テストツール C++testの詳細はこちら

Top