オープンソースのC++コードがセキュリティリスクを招く仕組み
Snyk Security Research Team
2022年8月22日
0 分で読めますオープンソースのライブラリやフレームワークは、開発プロジェクトをすばやく始めるのに役立ちます。オープンソースを活用すれば、車輪の再発明をしたり、すでに解決済みの問題に対するソリューションを開発したりすることなく、開発者は優れた成果を生み出せます。
しかし、プロジェクトにコードを追加することには、エラーや悪意によって入り込んだ潜在的な脆弱性を持ち込むリスクが常に伴います。
この記事では、オープンソースコードがソフトウェアサプライチェーンに脆弱性をもたらす仕組みを解説します。また、自動脆弱性スキャナーを使って、C++のオープンソースコードに潜む脆弱性を特定する方法も紹介します。
オープンソースコードがセキュリティリスクを招く仕組み
オープンソースソフトウェアのエコシステムは、複雑につながり合っています。コードにオープンソースコンポーネントを1つインストールすると、依存関係も一緒に取り込まれます。それぞれの依存関係にどのようなセキュリティ上の問題が含まれているかを継続的に把握するのは困難です。また、パッケージのメンテナーが脆弱性をすぐに修正してくれるとは限りません。そのため、コードベースに含まれるオープンソースパッケージに、未修正の脆弱性が残っている可能性があります。
SnykとLinux Foundationによる最新の調査では、オープンソースプロジェクトの脆弱性修正にかかる期間が、2018年の49日から2021年には110日へと着実に延びていることが示されています。オープンソースプロジェクトの脆弱性修正には、プロプライエタリプロジェクトよりも約20%(18.75%)長い時間がかかります。こうした複雑さから、既知の脆弱性を含むオープンソースアプリケーションは、ハッカーにとって格好の標的となります。
CやC++などの低水準プログラミング言語では、メモリの割り当てを開発者が行うため、バッファーオーバーフローの脆弱性が広く見られます。CやC++は、バッファーの指定範囲を超えてクライアントがデータにアクセスしたり書き込んだりすることを防ぎません。そのため、C++のオープンソースプロジェクトは脆弱性の影響を受けやすくなります。メモリが適切に管理されていないアプリケーションでは、攻撃者がこの脆弱性を悪用し、実行可能なコードをプログラムに挿入する可能性があります。
たとえば、GNU C Libraryのlibresolvライブラリで見つかったGlibcのバグを考えてみましょう。このバグにより、ライブラリ関数getaddrinfoの使用時に、Glibcがバッファーオーバーフロー攻撃にさらされました。
攻撃者は、クライアントをだまして悪意のあるドメインを検索させることで、この脆弱性を悪用できます。その後、バグを引き起こすペイロードを返します。クライアントにroot権限がある場合、システムが侵害され、中間者攻撃につながるおそれがあります。GlibcはLinuxカーネルを使用する何百万ものシステムで利用されているため、脆弱性を含むバージョンのGlibcを実行しているシステムは、いずれも影響を受ける可能性があります。
ソフトウェアサプライチェーンとは?
「サプライチェーン」という用語は、もともと製造業で使われていました。たとえば自動車メーカーは、一部の部品を自社で製造し、ほかの部品を別の企業から購入することがあります。つまり、自動車が所有者のもとに届くまでに、さまざまなツールを使う多くの人が製造に携わっています。
ソフトウェアでも、サプライチェーンの仕組みはほぼ同じです。ソフトウェアサプライチェーンとは、開発からデプロイまで、コードに組み込まれるものやコードに関わるあらゆる要素を指します。これには、コードやバイナリ、プロジェクトに携わった開発者、デプロイ先のリポジトリが含まれます。さらに、ビルドツール、パッケージングスクリプト、アプリケーションインフラストラクチャも含まれます。サプライチェーンのセキュリティは極めて重要です。
ソフトウェアサプライチェーンは多くの要素で構成されているため、非常に複雑になることがあります。ハッカーはその複雑さにつけ込みます。
ソフトウェアサプライチェーンの脆弱性
ソフトウェアサプライチェーン攻撃では、悪意のある攻撃者が、攻撃対象につながる上流のコンポーネントを利用してアクセス権を得ます。ソフトウェアを配布または実行するサービスが標的になることもあります。この場合、上流のコンポーネント自体が必ずしも攻撃対象とは限りません。アクセスするための手段として利用されるだけです。
サプライチェーンにおける主な標的は、依存関係、パイプライン、パイプラインの依存関係の3つです。
依存関係
攻撃者は、開発者がアプリケーションの作成時に取り込むオープンソースの依存関係を標的にします。一般的なオープンソースパッケージの既知の脆弱性を悪用してマルウェアを仕込むと、そのパッケージを依存関係としてインストールしたソフトウェアアプリケーションが危険にさらされます。ソフトウェアアプリケーションには、さらに別の依存関係を持つ依存関係が複数含まれる場合があるため、潜在的な脆弱性を追跡するのは困難です。そのため、依存関係は格好の標的になります。
パイプライン
パイプライン攻撃では、攻撃対象領域が広い継続的インテグレーション/継続的デプロイ(CI/CD)パイプラインを悪意のあるユーザーが標的にします。パイプラインは、デフォルト設定、セキュリティ認証情報、データベース、プロプライエタリコードにアクセスできます。そのため、攻撃者がCI/CDパイプラインに悪意のあるコードを挿入して侵害すると、そのパイプラインを利用するアプリケーションにバックドアを仕掛けることができます。
パイプラインの依存関係
攻撃者は、ビルド環境へのアクセスを得るために、パイプラインの依存関係を標的にすることもあります。たとえば、Codecovの侵害事件では、攻撃者がDockerイメージの認証情報を使ってbashスクリプトのアップローダーを更新しました。スクリプトを変更し、Codecovのユーザーの環境変数を自分たちに送信させたのです。
オープンソースの依存関係に潜む脆弱性の特定
オープンソースコードには固有の問題が伴う可能性がありますが、それでも開発者は優れたものを生み出し、ほかの人の成果を土台に開発できます。ただし開発者は、プロジェクトで使用するオープンソースコードの品質を確認し、脆弱性を特定できなければなりません。しかし、ほとんどの組織にとって、使用前に手作業でコードレビューを行い、オープンソースコードを監査するために必要なリソースを確保するのは現実的ではありません。
サプライチェーンに含まれるC/C++の依存関係すべてについて、バッファーオーバーフロー、ヌルポインター、整数オーバーフローやアンダーフローなどの脆弱性を見つけるのは困難です。たとえば、ソフトウェアサプライチェーンで使われているオープンソースのC/C++コードにヌルポインターの脆弱性があると、ハッカーに悪用されてクラッシュにつながる可能性があります。アプリケーションコードに脆弱性がなくても、オープンソースコードに脆弱性があれば、アプリケーションは安全ではありません。
オープンソースの依存関係に潜む脆弱性を特定する主な方法は2つあります。すべての段階で信頼できる貢献者が関わる安全なソフトウェアサプライチェーンを構築すること、そしてSnyk for C/C++などの自動脆弱性スキャナーを使うことです。
安全なソフトウェアサプライチェーンの構築
サプライチェーンの各貢献者を追跡し、信頼できることを確認するのは、理論上は有効な解決策ですが、実際に実施するのは非常に困難です。ソフトウェアサプライチェーンには、アプリケーションで使われる複数のライブラリやコンポーネントを担当する多くの開発者が関わっています。
Snyk for C/C++などの自動脆弱性スキャナー
より現実的な解決策は、オープンソースコードを分析してセキュリティ上の脆弱性を検出することです。ただし、手作業でスキャンすると時間がかかり、ミスも起こりやすくなります。ベストプラクティスは、Snykのような自動脆弱性スキャナーを使って、オープンソースのC++コードをスキャンすることです。
Snyk Open Sourceを使うと、開発者は使用しているオープンソースのC++コードを可視化できます。Snyk CLIはファイルをデジタル署名(ハッシュ)に変換し、そのハッシュをSnykのデータベースと照合して、一致するオープンソースコンポーネントの一覧を作成します。この一覧をSnyk Vulnerability Databaseと照合することで、脆弱性を特定できます。
個々のファイルをスキャンする他の脆弱性スキャナーとは異なり、Snykはファイルのコンテキストを考慮します。READMEファイルやインストールスクリプトなどの補助ファイルを利用することで、誤検知の脆弱性レポートを最小限に抑えます。これにより不要なノイズが減り、開発者は修正が必要な箇所に集中できます。
脆弱性が特定されると、SnykはIDEまたはCLIで開発者に通知し、ほかのコードを壊さずに脆弱性を修正するために必要な最小限のアップグレードを自動で特定します。
まとめ
オープンソースソフトウェアの人気は高まっています。それに伴い、知らない人々が開発・保守するサードパーティ製のライブラリやコンポーネントを、より多くのアプリケーションが含むようになっています。こうしたライブラリは公開リポジトリで入手できるため、攻撃者はセキュリティの弱いものを悪用してアクセスできます。
C++プロジェクトでオープンソースコードを扱う際に脆弱性を避けるには、Snyk Open Sourceのような自動脆弱性スキャナーを利用しましょう。アプリケーション内のオープンソースC++プロジェクトをスキャンして脆弱性や悪意のあるライブラリを特定し、ソフトウェアの侵害を防ぐことができます。
Snyk for C/C++のドキュメントで、C/C++プロジェクトのスキャン方法をご確認ください。
CTFを始めよう
オンデマンドのバーチャル入門ワークショップを視聴して、CTFの課題の解き方を学びましょう。



