ソフトウェアサプライチェーンは、アプリケーションやウェブサイトのライフサイクルにおける重要な要素だ。現代のソフトウェア開発で一般的な相互依存関係やコンポーネントは、攻撃対象領域を拡大し、ときにはインフラに追加した堅牢なセキュリティレイヤーをハッカーが迂回できるようにしてしまう。
実際、コードベースにたった1つの欠陥があるだけで、サプライチェーン全体が侵害される可能性がある。問題は、現代のプロジェクトには膨大な数の依存関係があることだ。この状況は「依存関係地獄」と呼ばれる。依存関係自体にも依存関係があり、それが延々と続くからだ。そうした依存関係をすべて追跡しようとすれば、気が狂いそうになるだろう。
さらに、ソフトウェア開発はオープンソースプラットフォームやサードパーティーベンダーに大きく依存している。単純に、開発プロセスが速くなり、開発者に標準ライブラリが提供されるからだ。コードを保守する人や組織は多岐にわたるため、セキュリティ上の欠陥を防ぐのはかなり難しい。
おそらく、これがパッケージマネージャーほど明白に表れる場所はないだろう。最近、RubyGemsのパッケージリポジトリは、重大な脆弱性として最近記録されたCVE-2022-29176を修正した。RubyGems.orgはRubyコミュニティ向けのジェムホスティングサービスであり、JavaScriptの世界における公式レジストリであるNPMのような存在だ。
これらの巨大なプラットフォームは、数十万のパッケージをホストし、数百万回ダウンロードされているうえ、常に攻撃を受けている。ハッカーは定期的に乗っ取り、依存関係混乱、タイポスクワッティング攻撃を試みており、今では自らを妨害してしまうリスクさえある。
関連記事:ハッカーはソフトウェアサプライチェーンをいかに侵害するか。
RubyGemsの脆弱性を詳しく見る
CVE-2022-29176の欠陥は、Rubyプログラミング言語コミュニティ全体向けのパッケージレジストリであるRubyGems.orgで発見された。この欠陥により、「その権限を持たないユーザーであっても、特定のジェムを削除して置き換える」ことが可能だった。
ただし、ほかにも条件があった。ジェム、つまりRubyパッケージの名前に「30日以内に1つ以上のダッシュが含まれる、または100日を超えて更新されていない」必要があったのだ。しかし、プラットフォーム上の多数のジェムに一致する可能性があった。
脅威アクターは、正規のジェムの内容を、認証情報を盗むスクリプトや暗号資産マイナーに置き換えることができた。重大な脆弱性である。
RubyGems.orgにはジェム所有者からの苦情が寄せられていないため、この重大な脆弱性がまだ悪用されていない可能性は高い。いずれにせよ、Ruby用パッケージマネージャーのBundlerは、「CIとデプロイ時にはBundlerを--frozen or --deployment使用する」ことを推奨している。
このベストプラクティスにより、Rubyアプリが乗っ取られたバージョンへひそかに切り替わるのを防げる。まさにそれこそが、ハッカーがこのようなエクスプロイトで実現しようとしていることだ。
過去にエクスプロイトの被害を受けていないかアプリを監査する必要があるユーザーは、Gemfile.lockファイルを調べ、バージョン番号が変わっていないにもかかわらず、ジェムで発生した望ましくないプラットフォーム変更を探すとよい。
関連記事:SBOM:ソフトウェアサプライチェーンの安全確保。
プラットフォームは攻撃を受けやすい
RubyGemsであれNPMであれ、あるいはPythonパッケージ向けのpipであれ、このような大規模プラットフォームはソフトウェアサプライチェーンの重要な一部だ。NPMは、数百万のプロジェクトやユーザーに影響を及ぼすさまざまなキャンペーンで、たびたびニュースの見出しを飾っている。
JFrog Security Researchチームは最近、検知した新たなNPMサプライチェーン攻撃は、以前Azureで報告されたものと類似している。ハッカーはドイツの産業企業、Bertelsmann、Bosch、Stihl、DB Schenkerを標的に、依存関係混乱攻撃を仕掛けた。
研究者らは、これは「非常に標的を絞った」攻撃だと述べた。Jfrogは記事を更新し、執筆時点では、攻撃の背後にいるのが実際の脅威アクターなのか、それとも「非常に攻撃的な」ペンテスターなのか判断できなかったと説明した。
さまざまなIoC(侵害の痕跡)が存在したが、ハッカーはNPM上で標的の名前を隠す手間をかけず、簡単に検知・逆解析できる公開オブファスケーターを使っていた。サイバー犯罪者の行動としては、かなり異例に見える。
依存関係混乱とは、非公開パッケージの名前を使い、より高いバージョン番号の公開パッケージを作成する手法だ。ユーザーがインストールや更新を実行すると、パッケージマネージャーが混乱し、最新のものに見えるパッケージを取得してしまう。
サプライチェーンを攻撃したいハッカーには、数多くの機会がある。依存関係混乱やタイポスクワッティングは巧妙な手法だが、必ずしも実行しやすいとは限らない。
所有者やメンテナーの認証情報を盗む方が、より現実的なアプローチかもしれない。攻撃者は正規ユーザーになりすまして、数百万件のインストール先にマルウェアやバックドアを配布するなど、あらゆる悪用を行えるからだ。
関連記事:コードデバッグとコードセキュリティに役立つ主要ツール。
サプライチェーン攻撃から身を守る方法
ほとんどの場合、サプライチェーンの脅威に対してできる最善の対策は被害を軽減することだ。しかし、リスクを減らすために実行できる簡単な対策もある。
- デプロイとCIに関するベストプラクティス(例:Bundlerの推奨事項)に従う
- 定期的にセキュリティチェックと監査を実施し、テストしていないものを本番環境にデプロイしない
- タイポスクワッティング攻撃を防ぐため、非公開レジストリと同じ名前で公開レジストリを登録する
- より厳格なベンダーポリシーを使用する(例:インストール中の予期しない更新を防ぐため、「*」や「^」ではなく正確なバージョン番号を指定する)
- パッケージの所有者またはメンテナーである場合は、多要素認証を有効にする
- 本番環境に設定ファイルやソースマップを決してデプロイしない
- すべての依存関係を最新に保つ
最後の点は、やや逆説的に思えるかもしれない。ハッカーは更新メカニズムを侵害し、被害者をだましてマルウェアをデプロイさせようとしているからだ。しかし、脅威の状況はあまりにも急速に変化しているため、セキュリティパッチを軽視することはできない。古いコンポーネントは、既知の脆弱性を悪用できるかどうかを確認する際に、ハッカーが最初に調べる要素の1つだ。
ソフトウェアサプライチェーンは危険に満ちている。それでも、外部リソースは開発を高速化し、プラクティスを標準化するうえで重要だ。開発者は、自分が保守していないコードを管理することはできない。しかも今日では、プロジェクト内のコードの大半は自分たちが書いたものではない。最善の答えは、セキュリティプラクティスを常に徹底することだ。





