Java を使った Web アプリにおける脆弱性対策
Java は業務システムをはじめ、Web アプリケーション、Android アプリの開発等で世界中で幅広く使われている言語です。
プラットフォームに依存しない環境と堅牢さ、ライブラリの多さ、需要の多さから、大規模システム、エンタープライズ向けアプリケーションの開発でも多く採用されています。
実際に業務において Java を用いて開発・運用しているプロジェクトも多いのではないでしょうか。
一方で、稼働しているアプリケーションをセキュアな状態に維持するためにも、Java に関わる脆弱性を把握することは非常に重要です。
今回は Java ベースの Web アプリケーション開発に焦点を当て、新しく出てくる脆弱性とその対策方法について開発者寄りの視点で解説します。
Java で構築された Web アプリにおける脆弱性が潜む場所
Java で構築された Web アプリケーションにおいて、脆弱性が潜む場所は大きく以下の 3 つに分類されます。
- JDK / アプリケーションサーバ
- Java フレームワーク / ライブラリ
- 開発者が独自に実装したコード
それぞれに注意を払う必要がありますので、ひとつずつ見ていきましょう。
1. JDK / アプリケーションサーバ
まず Java アプリケーションの基礎にあたる JDK とアプリケーションサーバについてです。
Java の本体ともいえる JDK ですが、OpenJDK では 3 ヵ月に 1 回のサイクルで脆弱性の修正情報が公開され、セキュリティアップデートが行われています。
実際、2020 年 4 月のリリースでは 14 件の脆弱性に対応したことが記されています。
脆弱性のリスクに大小があるとはいえ、OpenJDK 自身も脆弱性アドバイザリで「できるだけ早く、利用している JDK ディストリビューションを最新バージョンに更新すること」を推奨していることから、定期的に JDK 本体のアップデートを行っていく必要があることが見てとれます。
またアプリケーションサーバにおいては、著名なもので Tomcat, Jetty, WebSphere 等がありますが、いずれも過去のバージョンに脆弱性があることが公表されています。
脆弱性を放置すると、脆弱性を突かれることでリモードコード実行や権限奪取、不正アクセスにつながる可能性が格段に高まります。
2. Java フレームワーク / ライブラリ
Java の著名なフレームワークとして、Apache Struts, Spring, Play Framework, Spark Framework 等がありますが、いずれも過去のバージョンに脆弱性があることが公表されています。
また、利用しているフレームワーク本体だけではなく、そのフレームワークに依存している依存ライブラリにも注意が必要です。
一例として、Java で JSON データを読み書きできるライブラリとして jackson-databind がありますが、2020 年だけでも16 件以上の脆弱性が NVD(脆弱性データベース)より公表されています。
たとえば spring-boot-starter-web というフレームワークライブラリを導入すると、内部で jackson-databind が用いられているため、結果として jackson-databind をプロジェクトが導入されることとなります。
このように間接的に導入された依存は、一般的に「間接依存」と呼ばれます。
以下はspring-boot-starter-web:2.1.5.RELEASEにおける依存関係です。
上記の依存関係では jackson-databind:2.9.8 が導入されていますが、このバージョンには、サーバ上の任意のローカルファイルを読み取ることができる脆弱性があります(CVE-2019-12086)。
間接依存ライブラリの脆弱性を手動で確認するのは困難であるため、対策としてyamory 等のツールを用いた脆弱性検知・管理が必要になります。
このように、OSS のフレームワーク / ライブラリに潜む脆弱性は深く複雑な課題です。
OSS のフレームワーク / ライブラリを使う際には、その OSS 自身の脆弱性リスクも把握する必要があるという意識を持つようにしましょう。
3. 開発者が独自に実装したコード
開発者によるコード実装においても、実装を誤ればXSS(クロスサイトスクリプティング) や SQL インジェクション といった脆弱性に繋がります。
コーディングによって引き起こされる脆弱性の発生を最小限に抑えるために、開発者自身がよりセキュアにコーディングをし、セキュリティリスクの理解を深めることが大切です。
セキュアコーディングの観点では、ガイドラインやドキュメントが公開されていますので、参考にすると良いでしょう。
- Secure Coding Guidelines for Java SE(Oracle)
- Java コーディングスタンダード CERT / Oracle 版(JPCERT コーディネーションセンター)
- Find Security Bugs - Bug Pattern
上記の他にもコードベース以上に包括的に Web アプリケーションのセキュリティを評価できるOWASP ASVSも参考となるでしょう。
また、実装したコードについては定期的にセキュリティ診断(脆弱性診断・検査)を実施することをお勧めします。
脆弱性を知る・見つけるには
Java に関わる多くの脆弱性については、脆弱性が公表される際にCVEと呼ばれる個々の脆弱性を管理するための固有の識別番号が採番されます。
CVE を元に脆弱性情報を閲覧できるサイトとして、 NVD や、日本語では JVN (Japan Vulnerability Notes) で情報を得ることができます。
NVD では、新しく発行された CVE の情報を RSS などで配信しているため、そちらを利用するのも良いでしょう。
「Web アプリケーションのセキュリティとは」でもご紹介したように、脆弱性が含まれたバージョンを利用し続けると、脆弱性を突かれて不正アクセスにつながる可能性が高まります。
特に「エクスプロイトコード」が流通していると、格段にリスクが高まると言えます。
自身の Web プロジェクトで使用している Java の環境とバージョンを把握した上で、定期的にこれらの情報をウォッチして対策していくことが大切です。
どうやって脆弱性に向き合い、対策していけば良いか
日々新しい脆弱性情報が公表され、脆弱性対応が行われた新しいバージョンがリリースされていく中で、自社のプロジェクトで使っている JDK / アプリケーションサーバ / フレームワーク / ライブラリのパッケージとそのバージョンを把握し、脆弱性が公表されているかどうかを日々ウォッチし続けることは容易ではありません。
また脆弱性があることが確認できても、修正方針を取り決めて対策を行っていくことはリソース・工数の面からも非常に労力のかかることです。
とはいえ古いバージョンのまま放置すると、付随してライブラリも新しいバージョンにアップデートできなくなるという事態にもなりえます。
利用中のバージョンで脆弱性が発見されたとしても、対策をすぐに行うことが難しい状況となると身動きがとれなくなり、日に日に攻撃にさらされるリスクが上がっていく一方となってしまいます。
そのため、最新バージョンにアップデートしていける仕組み・体制を整え、アップデートを継続して実施していくこと(いわゆるパッチマネジメント)が重要になってきます。
それでは、Java ベースの Web アプリケーションにおいて、Web 開発者はどのように脆弱性と向き合い、セキュアな環境にしていくとよいのでしょうか。
JDK とアプリケーションサーバ : 定期的にアップデートする計画を立てる
まずは Java アプリケーションの基盤となる JDK についてです。
Java の場合、OpenJDK をベースに OracleJDK, Amazon Corretto, AdoptOpenJDK 等、いくつかのディストリビューションがリリースされています。
利用している JDK のリリースに合わせてサポート期間を確認し、またアップデートがないか定期的に確認するようにしましょう。
Java のリリースサイクルに則ったアップデートを実施するのが困難な場合は、ベンダーの有償サポートを受けるといった対応も検討してみてください。
アプリケーションサーバも同様、JDK の最新バージョンに追従したものを利用し、セキュリティアップデートの情報に注視するようにしましょう。
フレームワーク / ライブラリ : プロジェクト管理ツールを使い、パッケージのバージョンを把握する
続いてフレームワーク、ライブラリについてです。
対応方針の基本は「パッチマネジメント(アップデート)」であり、脆弱性管理の出発点は、利用しているライブラリを把握することから始まります。
Java においては、Gradle や Maven といったビルドツールでライブラリの管理を行うことがデファクトスタンダードになってきており、実業務で利用されている方も多くいらっしゃるのでないかと思います。
まだお使いでない方、もしくは直接ライブラリのソースをダウンロードして利用している方は、是非この機会にプロジェクト管理ツールを導入して「Java のライブラリとそのバージョン」を一元管理できるようにしましょう。
Java の Web アプリケーションをよりセキュアに運用ができる礎となります。
たとえば Gradle の場合ですと、build.gradle という設定ファイルに記述されたバージョン番号を変更することで容易にアップデートが行えるようになるため、ある特定のライブラリに脆弱性が発見された際も対応が容易になります。
yamory を導入することで Java フレームワーク / ライブラリの脆弱性チェックが行えます
yamory は、Java のパッケージ管理でよく用いられる Gradle や Maven のパッケージ管理データをスキャンすることで、利用しているフレームワーク / ライブラリに脆弱性情報が出ていないかをチェックすることができるサービスです。
手作業で確認するのは困難な「間接依存となっているライブラリの脆弱性」も検知できるため、個々のライブラリが持つ脆弱性についても早期に気付くことができます。
また、発見された脆弱性にエクスプロイトコードと呼ばれる攻撃コードが流通している場合は、非常にリスクの高い脆弱性であることが一目でわかるようになっています。
無料でトライアルができますので、セキュアな Web アプリケーション運用のためにもぜひお試しください。