数十年にわたり、Cとその直系の派生言語は、システムプログラミングで選ばれるプログラミング言語であり続けてきました。1970年代初頭に開発されたCは、アセンブリ言語からの大きな進歩でした。それから50年が経った今、さらに優れた選択肢があります。
1970年当時、コンピューターセキュリティはほとんどの人に意識されておらず、その後も長年にわたって同様でした。インターネット上で最初の重大なセキュリティ脆弱性が発生したのは、それから何年も後の1988年です。これは「インターネットワーム」として知られ、メモリ内の配列が境界外のインデックスで参照されるバッファオーバーフローを悪用したものでした。
C++を含むC言語系では、配列の境界チェックは行われません。配列が正しくアクセスされるようにするのは、プログラマーの責任です。そのため、バッファオーバーフローエラーがよく発生します。さらに悪いことに、意図的にバッファオーバーフローを引き起こし、本来アクセスすべきでないメモリ領域にアクセスすることも容易です。
バッファオーバーフローは、メモリ安全性の欠如の一例にすぎません。ほかにも、ポインター演算やダングリングポインター(解放後使用バグとも呼ばれます)などの関連例があります。現在では、さまざまな手法を用いて、その言語で記述されたプログラムにメモリ安全性の問題がないことを保証するプログラミング言語が数多くあります。C言語ファミリーにはそのような保証はありません。メモリ安全性は、これらの言語の設計目標ではなかったためです。
セキュリティ脆弱性の約70%は、メモリ安全性の侵害に起因します。この主張は、圧倒的な量のデータによって裏付けられています。メモリ安全性に起因するものは次のとおりです。
- 実環境で検出され、公開された悪用済みの脆弱性の67%(Google Project Zero 2021の推定による)。
- Androidの脆弱性の90%(Googleによると)。Rustの採用により、この割合は最近低下しているものの、リモートから悪用可能な脆弱性の89%は、依然としてメモリ安全性に関連しています。
- Microsoftの脆弱性の70%(Microsoftによる)。
- Appleが最近修正した脆弱性の大半(対象:Catalina、Big Sur、Monterey、Safari、iOS、tvOS、watchOS)
2022年7月、Chrome 103.0.5060.134で修正された脆弱性の6分の5は、メモリ安全性に関する問題でした。メモリ安全性のバグを排除できれば、非常に大きな効果があることは明らかです。その方法、つまりメモリ安全なプログラミング言語を使用することは、業界では長年にわたり知られてきました。従来、その課題は常に、パフォーマンス面でのコストでした。メモリ安全性は重要であるため、従来のオーバーヘッドを伴わずに実現する新たな戦略が模索されてきました。現在では、実行時コストをほとんど、あるいはまったくかけずに、メモリ安全性に関するエラーを排除する方法が確立されています。Rustなどの言語では、型システム設計の革新により、コストの高いランタイムサポートを必要とせずにメモリ安全性を保証します。
ここから導かれる結論は明白です。C/C++(より一般的には、メモリ安全でない言語)で新たなシステムコードを書くのはやめるべきです。
これは、既存のコードを大規模かつ無差別に書き換えるよう求めるものではありません。既存のソフトウェアの置き換えにはコストがかかり、リスクも伴います。しかし、既存のコードベースにメモリ安全でないコードをさらに追加して問題を悪化させることは、業界全体でやめなければなりません。既存のコードについては、信頼できないユーザー入力の検証や処理を担うコンポーネント、特権コンテキストで実行されるコンポーネント、サンドボックス外で実行されるコンポーネントなど、最も機密性の高いコンポーネントの書き換えを優先してください。
この見解は広く支持されているものの、依然として異論を唱える人もいます。ここでは、現状維持を支持する一般的な主張と、それに対する私たちの回答を紹介します。
- バグはプログラミング言語に固有のものではありません。
- 脆弱性の多くは、メモリ安全性に関するバグに起因します。Rustのようなメモリ安全な言語では、メモリ安全性に関するバグは発生しません。そのため、メモリ安全な言語を使用すれば、脆弱性の多くを未然に防ぐことができます。
- コードレビューでバグを発見できます。
- 調査結果によると、コードレビューによって改善が見込める一方で、多くの問題が見落とされることも少なくありません。すべての問題を発見できるわけではないことは明らかです。
- 安全でないモジュールがあれば、そもそもの意義が失われます。
- 安全でないコードは、ごく小さなコード領域として明確に区分されるため、その検証にリソースを集中できます。
- メモリ安全な言語の実装にもバグが存在する可能性があります。
- 確かにその可能性はありますが、確率ははるかに低くなります。コンパイラは比較的小規模で、厳格にテストされています。また、1つのプログラムのバグを修正する場合とは異なり、コンパイラを修正すれば、そのコンパイラでコンパイルされたすべてのプログラムが自動的に修正されます。
- このようなミスをするのは、初心者か能力のないプログラマーだけです。
- それどころか、上記のデータは、ChromeブラウザやWindowsおよびmacOSオペレーティングシステムなど、大規模なシステムプロジェクトから得られたものです。これらのプロジェクトには、業界でも特に優秀で経験豊富な開発者が携わっていますが、それでもメモリ安全性の問題が生じています。
- ベストプラクティスに従えば、こうした問題は回避できます。
- 上記をご覧ください。前述のチームは非常に厳格なプラクティスに従い、利用可能な最良のツールを使用しています。
- すべてのコードを書き直すのは現実的ではありません。
- すべてのコードを全面的に書き直すべきだと主張しているわけではありません。むしろ、重要な要素(高い権限、広い攻撃対象領域、セキュリティ保証の中核を担うもの)に重点を置き、新しいコードはメモリ安全な言語で記述するアプローチを推奨します。
- パフォーマンスが不十分である。
- RustのパフォーマンスはC/C++とほぼ同等です。わずかな差を理由にセキュリティリスクを許容することはできません。また、Rustプログラムの方が高速になる場合もあります。
- Rustのようなメモリ安全なシステムプログラミング言語は、まだ新しすぎる。
- RustはLinuxカーネルにも採用されつつあります。
- FirefoxなどのWebブラウザでは、その大部分がRustで記述されています。
- Googleは、Androidに大量のRustコードを追加しましたが、脆弱性は1件も確認されていません。
- 静的解析、ファジング、サンドボックス化など、ほかの解決策もあります。
- セキュリティには多層的なアプローチが必要です。
- サンドボックスには限界があります。
- 最善の最新のC++プラクティスをもってしても、脆弱性の急増を食い止めることはできません。
上記の点に関する詳細な考察については、「メモリ安全性の欠如の定量化とそれに対する反応」をご覧ください。
反対意見はあるものの、必要な変革に向けた機運は高まっています。たとえば、Open Source Software Security Foundation(Linux Foundationが支援)には多額の投資が行われています。メモリ安全性は、米国上院の報告書やNSAでも取り上げられています。Consumer Reportsも、企業や州政府機関に一連の提言を行い、この動きを加速させ得るさまざまなインセンティブの特定に取り組んでいます。
要約すると:
過去50年間で、コンピューティングが社会にとって持つ重要性は飛躍的に高まりました。また、ここ数十年で、コンピューティングインフラを取り巻く脅威の状況も大きく変化しています。しかし、コンピューティングシステムの構築に使用するプログラミング言語は、それに応じて変化してきたわけではありません。メモリ安全性の欠如は、ソフトウェアにおけるセキュリティ脆弱性の最大の原因です。これは特定の種類のソフトウェアに限った問題ではなく、メモリ安全でない言語が使用されているあらゆる場所で、メモリ安全性の問題が多発しています。件数で見ても、これに匹敵する脆弱性の分類はほかにありません。
今や、この深刻化する問題に対処する手段は整っており、業界全体で取り組むことが極めて重要です。幸い、この状況への認識は広がりつつありますが、問題は差し迫っており、一刻の猶予もありません。
著者について
関連するブログ記事

SOAS 2025:足並みの乱れが凡庸さを招く
AI導入における方針の不一致は、非効率を招きます。セキュリティ、自動化、導入の各戦略を整合させ、AIの可能性を最大限に引き出す方法をご紹介します。

WebAssemblyが重要な理由
WebAssembly(Wasm)は、あらゆるプラットフォームで高性能なアプリケーションを実現する、ポータブルで高速かつセキュアなバイナリ命令セットです。
インフラストラクチャは依然として格好の攻撃経路
クラウドコンピューティングでは、APIやドラッグ&ドロップ式の設定ツールを活用し、ネットワークやインフラストラクチャを敬遠する人がそれらを直接扱わずに済むようにすることで、インフラストラクチャへの対応を不要にすることが長年追求されてきました。しかし、インフラストラクチャを無視することも、攻撃の主要な標的であるという事実を見過ごすこともできません。
堅牢なデータアーキテクチャがもたらす戦略的メリット
適切に構築されたデータアーキテクチャがもたらす効果は、業務プロセスの改善にとどまりません。戦略的な業務効率の向上、より深いビジネスインサイトの獲得、隣接するビジネス機会への展開にもつながり、これらすべてをより俊敏に実行できるようになります。
デジタルワークフローにおける不正検知には、データだけでは不十分
2019年には、業界全体でクレジットカード詐欺の試みが約25万件確認されました。これは約2分に1件の割合です。今日、不正を検知するには、デジタルワークフロー上のできるだけ多くのポイントから収集したデータを相互に関連付け、手作業によるデータ処理をはるかに上回る速度で分析する能力が求められます。