ソフトウェアに潜在的に存在する脆弱性を調査するに当たり、プログラミング言語がデータ型や演算をどのように実装しているのか、またそれらがプログラムの実行にどのような影響を与えるのかについて理解していることは極めて重要です。
プログラムの実行ファイルをアセンブリレベルでコードレビューできるプログラマであれば、データがマシン上でどのように保存され、操作され、操作の結果がどのような結果をもたらすことになるのかを明確に理解することができるでしょう。しかし、同じことをソースコードレベルで行う場合、ディテールはプログラミング言語による抽象化のベールに覆われてしまいます。まさにこのプログラミング言語による抽象化が、ソフトウェアに微妙な脆弱性を生み出し、それが誰にも気づかれることなく存在し続ける状況を生み出してしまうのです。
セキュアコーディングを実践するプログラマには、この抽象化を生み出すプログラミング言語の実装の詳細と、それがセキュリティに影響を与える状況を生み出すコーナーケースについての理解が求められるのです。
特に、C/C++言語はこの「抽象化」のメカニズムが曖昧であるために、脆弱性を作り込みやすいという性質を持っています。ただ、CやC++言語でコーディングする限りこの言語による抽象化の罠から逃れられないからといって、C/C++でセキュアなコードを書くことが不可能であるということにはなりません(注7)。
幸い、プログラマが誤解しやすく脆弱性を作り込みやすいポイントは明らかにされており、コーディング規約としてノウハウがまとめられています(注8)。第2回以降の連載で、具体的なテクニックやノウハウを見ていくことにしましょう。
注7:「Cでコーディングすると脆弱性を作り込むのは不可避」「C言語は捨てて、別な言語で開発すべき」という話を聞くことがありますが、例えば本連載を担当する戸田が愛好するOS、OpenBSDプロジェクトの存在は、Cを使ってもセキュアなシステムを開発することが可能であることの生きた証明であると言えるのではないでしょうか。
注8:CERT C セキュアコーディングスタンダード(https://www.jpcert.or.jp/sc-rules/)
次回以降、プログラマが間違いを犯しやすい、C/C++言語を使ったセキュアコーディングで特に重要となるトピックスを取り上げます。脆弱なコードの実例を検討しながら、同じ間違いを繰り返さないためにはどのようなコードを書くべきか、考えていきたいと思います。
C言語の言語仕様は昨年2011年に改訂され、ISO/IEC 9899:2011という言語規格の第3版(通称C11)が国際標準になりました。また、C++言語については、ISO/IEC 14882:2011とこちらも第3版(通称C++11)が最新の言語標準となっています。本連載では、これらの規格改訂で新たに導入された概念や機能、また廃止された内容のうち、セキュリティに関するものについて、できる限り紹介していく予定です。
なお、本連載の内容は、著者らが翻訳した下記の書籍の内容を一部ベースにしています。興味のある方はこちらもご参照ください。
Robert C. Seacord著『C/C++セキュアコーディング』ASCII、2006
Robert C. Seacordほか著『CERT C セキュアコーディングスタンダード』ASCII、2009
Copyright © ITmedia, Inc. All Rights Reserved.