Skip to main content

DepGraphを活用したGoプロジェクトのセキュリティテストの強化

著者

Antonio Gomes

2020年8月26日

0 分で読めます

Snyk CLIによるGoプロジェクトのセキュリティテストが大幅に高速化しました。スキャン時間が90%以上短縮されるケースもあります。この改善は、今後ほかの言語にも導入される予定です。SnykがKubernetesほどの規模の巨大なプロジェクトにも対応できるよう、スキャン方法を変更したことで実現しました(詳しくは後述します)。

依存関係、依存関係、そしてさらに多くの依存関係

アプリケーションやプロジェクトにはさまざまな形態がありますが、共通点がひとつあります。それは、オープンソースの依存関係を含んでいることです。SnykのLanguageチームの一員として、最初は小規模で依存関係もわずかだったプロジェクトが、すぐに規模を拡大し、直接依存と推移的依存が数十、場合によっては数百に及ぶようになることも、自信を持ってお伝えできます。

プロジェクト内の依存関係の数は、スキャンのパフォーマンスに直接影響することがあります。Goプロジェクトのスキャンやモニタリングが遅いというユーザーの声を受け、ユーザーとプロジェクトの成長に合わせて拡張できる、長期的な解決策を検討し始めました。最終的に選んだのは、アプリケーションのデータ構造をdependedencyTreesからdependencyGraphsへ移行することでした。

DepTreesとDepGraphs:セキュリティテストの強化

プロジェクトのマニフェストファイルをスキャンすると、呼び出されるさまざまなオープンソース依存関係(直接依存と推移的依存)をすべて列挙したdependencyTreeが作成されます。この方法は小規模なプロジェクトには十分でしたが、大規模なプロジェクトでは問題が生じました。dependencyTreesが大きくなりすぎて、メモリを大量に消費するようになったのです。

具体的なイメージをつかむために、dependencyTreeを使って小規模なGoプロジェクトを処理する基本的な例を見てみましょう。

gopusheモジュール、Go 1.13、Firestoreやgo-kitなどの依存関係が表示されたgo.modファイルのスクリーンショット。

依存関係ツリーを使ってGoプロジェクトを処理する基本例

dependencyTreeを使った場合、この小規模なGoプロジェクトで解決された依存関係は次のようになります。

go-sample-tree.json内のGo依存関係ツリーが表示されたコードエディター。入れ子になったパッケージのバージョンと、プロジェクトファイル一覧が表示されたターミナル。

直接依存するオープンソースが3つだけでも、推移的依存を含めるとdependencyTreeのサイズは11MBになります。直接依存が100を超えるプロジェクトを想像してみてください。生成されるdependencyTreeは巨大になり、スキャンが遅くなるだけでなく、CLIスキャンがOutOfMemoryエラーでクラッシュする可能性も高くなります。

dependencyGraphのデータモデルなら、この問題を解決できます。頂点と辺を使うことで、同じ依存関係を何度も含める必要がなくなります。その結果、以下の画像に示すように、メモリ使用量を大幅に削減できます。

Goモジュールの依存関係グラフを示すJSONファイルと、関連ファイルの一覧を表示したターミナル出力が映るダークテーマのコードエディター。

先ほどの同じ基本プロジェクトで、今度はdependencyGraphのサイズが51KBになりました。11MBから大幅に削減されています。

パフォーマンスの向上、その先へ……Kubernetesのセキュリティスキャン

dependencyTreeからdependencyGraphへの移行は大きな効果をもたらし、Goプロジェクトで以前発生していた処理の遅さが解消されました。

特に印象的な成功例は、読者の皆さんもご存じかもしれないKubernetesのプロジェクトです。

以前のdependencyTreeデータモデルとプロジェクトの規模の大きさが原因で、Snykを使ったKubernetesプロジェクトの脆弱性スキャンには困難が伴っていました。

新しいdependencyGraphによって、こうした問題を解決できました。Snyk CLIでKubernetesのメインリポジトリをテストしても、今では高速に処理でき、生成されるファイルは1.1MBです。これほど大規模で多層的なプロジェクトとしては、十分に許容できるサイズです。

パッケージ名とバージョン情報が表示された、KubernetesのJSON依存関係マニフェストを映すターミナル。

今後の予定

大規模環境でのパフォーマンスがユーザーにとって重要な課題であることを踏まえ、言語やエコシステムへの対応を継続的に改善していきます。dependencyGraphへの移行もその一例であり、この変更に対するユーザーからの反応は非常に好評です。

前述のとおり、今回の変更は最近、Goプロジェクト向けのSnyk CLIに適用されました。Javaユーザーにも朗報です。Java GradleプロジェクトでもdependencyGraphへの移行が完了しました。こちらもCLIのみが対象です。

さらに良いことに、新しいデータ構造への移行を加速する予定です。まずCLIでほかの言語(npm, yarn, maven, sbt)に対応し、その後、CLI以外のGitベースのインテグレーションにも展開します。

続報をお楽しみに。それ以上に大切なことは、安全を守り続けることです。

CTFを始めよう

オンデマンドのバーチャル入門ワークショップを視聴して、CTFの課題の解き方を学びましょう。