Log4Shell みたいなことが起きた時に慌てるのは嫌だなということで、去年の年末以降は dependency-check や trivy のレポートとにらめっこしてる。 (実際には 0-day は防げないため、直接は関係しないが、芽を摘んでおくことは良いことであるはず。)
しかし、対応すればするほど build.gradle
がクソデカになっていくのがなかなか悩ましい。(これは他の言語のビルドファイルでも同じかもしれない。)
当たり前だがライブラリを使えば、その可能性は高まる。
↑の記事にもある通り、依存先が古くて駄目というのはよくある。
+ com.example:library-a:1.2.3 <- 設計や実装が完成してしまっているため、更新されることがもうない + com.example:library-b:2.3.4 <- ↑が更新されないため pom が古いままで脆弱性が出てる
一番良い方法は library-a
のメンテナに更新してもらうことであるが、library-a
の開発がアクティブでない場合は残念ながら期待できないであろう。
そのため、使用するライブラリの開発がアクティブかどうかは選定における重要な要素の一つである。
メンテナによる対応が期待できない場合は手元の build.gradle
に library-b
を「直接使わないのだが」明示するしかない。
そして、そういうことを繰り返すことで build.gradle
がクソデカになっていく...。
逆に不要なライブラリであれば、削るという対策もできる場合がある。 実際に不要なものが入っていることはそうそうないが、たまに記述ミスか何かで入ってるのを見かけることはある。
+ com.example:library-a:1.2.3 + com.example:library-a-test:1.2.3 + junit:junit
たとえば、開発者がテスト用のサブプロジェクトをうっかり依存を入れ込むと↑のようなことになる。 ちなみに junit は 4.x 系列だと最新じゃないとほぼヒットする (= Vulnerability がある) ため、だいたい気付ける。
こういう場合は exclude すれば OK である。
dependencies { implementation('com.example:library-a:1.2.3') { exclude module: 'library-a-test' exclude module: 'junit' } }
↑のような依存の場合は library-a-test
だけ exclude しても junit
は残るため、推移先すべてを指定しないと駆逐できない。(つまり、成果物に入ってしまう。)
また、別のライブラリが library-a
に依存している場合は、そちら経由で library-a-test
以下が成果物に入ってしまう。
そのため、すべての依存から library-a-test
と junit
を exclude するような書き方をするのが最善と思われる。
configurations { implementation.exclude module: 'library-test-a' implementation.exclude module: 'junit' }
こういうことをやって、少しずつ脆弱性のあるライブラリを成果物から取り除いていくことで安心して眠れるようになりたい。