Scala: build.sbt の依存関係管理とスキャン
Aikido は、Scalaの依存関係に含まれる既知の脆弱性(CVE)に加え、それらの依存関係が使用するマルウェアや危険なライセンスも検出できます。
Aikido はどのようにしてこれらの依存関係とその推移的な副依存関係(transitive subdependencies)を見つけているのでしょうか。
Scalaの場合、build.sbt ファイルをスキャンして依存関係を検出します。ただし、build.sbt ファイルには一部の依存関係について正確なバージョンが記載されていないことがある点に注意が必要です。これにより、Aikido がアプリケーション内のリスクを完全には検出できない場合があります。
そのため、各依存関係と副依存関係の正確なバージョンを含む build.sbt.lock のロックファイルを使用することを推奨します。
Aikido のセキュリティスキャンを容易にすること以外にも、ロックファイルを使用すべき理由があります。
- ロックファイルを使用することで、悪意のあるパッケージによるサプライチェーン攻撃から保護されます。この種の攻撃は増加傾向にあります
- ロックファイルを使用することで、全員が全く同じマイナーバージョンのパッケージを使用するためビルドがより予測可能になります。「自分の環境では動く」という事態が起きにくくなります
- ビルド時間の短縮: 依存関係解決が不要になります
これらの課題を浮き彫りにする最近の事例を見てみましょう。
// Original build.sbt without lock fileslibraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-http" % "10.2.+", "org.apache.spark" %% "spark-core" % "3.+", "com.datastax.cassandra" % "cassandra-driver-core" % "latest.release")Aikido は次のように報告しました。
- Akka HTTP に Critical な CVE が3件
- Spark に High レベルの脆弱性が2件
- Cassandra driver に Critical な脆弱性が1件
調査の結果、すべて誤検知(false positive)であることが判明しました。スキャナーは、実際に本番環境で使用されているものとは異なるバージョンを照合していたのです。
// What the scanner thought was runningakka-http 10.2.0 // Vulnerablespark-core 3.0.0 // Vulnerablecassandra-driver 4.0.0 // Vulnerable
// What was actually running in productionakka-http 10.2.10 // Securespark-core 3.3.2 // Securecassandra-driver 4.15.0 // Secure解決策: ロックファイルを追加する
Section titled “解決策: ロックファイルを追加する ”SBT Dependency Lock プラグインを使用して、プロジェクトのロックファイルを生成します。
手順1: SBT Dependency Lock プラグインを追加する
// In plugins.sbtaddSbtPlugin("software.purpledragon" % "sbt-dependency-lock" % "1.5.1")手順2: Lock Fileを生成する
// Run this command to resolve dependencies and generate lock filessbt "dependencyLockWrite"生成されるロックファイル(build.sbt.lock)は、すべての依存関係を明示的に定義します。
{ "com.typesafe.akka:akka-http_2.13": "10.2.10", "org.apache.spark:spark-core_2.13": "3.3.2", "com.datastax.cassandra:cassandra-driver-core": "4.15.0"}手順3: ロックされた依存関係を強制する
// Run this command to resolve dependencies and validate against lockfilesbt "dependencyLockCheck"代替手段: コンテナスキャン
Section titled “代替手段: コンテナスキャン ”ロックファイルはソースレベルでの優れた依存関係管理を提供しますが、コンテナスキャンはセキュリティ検証のもう一つの強力なアプローチです。コンテナにはコンパイル済みの成果物が含まれるため、本番環境の実際の状態を表しています。
コンテナスキャンの利点
Section titled “コンテナスキャンの利点 ”# Example Dockerfile showing what gets scannedFROM openjdk:11-jre-slim
# Your compiled artifacts are hereCOPY target/scala-2.13/your-app.jar /app/COPY target/scala-2.13/lib/* /app/lib/
# These are the actual versions that will run in productionRUN ls -la /app/lib/
# akka-http_2.13-10.2.10.jar# spark-core_2.13-3.3.2.jar# cassandra-driver-core-4.15.0.jarコンテナスキャンを使うべき場面
Section titled “コンテナスキャンを使うべき場面 ”コンテナスキャンは特に次のような場合に有効です。
- 本番対応の成果物を検証する必要がある場合
- ビルドプロセスに複数のステージが含まれる場合
- 本番環境で実行されている正確なバージョンを確認したい場合
- アプリケーションとそのランタイム環境の両方をスキャンする必要がある場合
コンテナスキャン vs. Lock Files
Section titled “コンテナスキャン vs. Lock Files ”| 観点 | コンテナスキャン | Lock Files |
|---|---|---|
| 検証タイミング | ビルド後 | ビルド前 |
| チェック対象 | コンパイル済み成果物 | ソースの依存関係 |
| 正確性 | 本番環境と完全一致 | 開発環境と完全一致 |
| 統合 | CI/CDパイプライン | 開発ワークフロー |
ベストプラクティス: 両方のアプローチを併用してください。コンテナスキャンは有用ですが、ロックファイルと組み合わせて使うことで最も効果を発揮します。