Skip to main content

Spring MVCアプリケーションでJavaのセキュリティ問題を解決する

Blog Header Spring MVC

2021年3月15日

0 分で読めます

Spring MVCフレームワークは、インタラクティブなWebアプリケーションを構築するための、よく知られたJavaフレームワークです。Model-View-Controllerアーキテクチャパターンを実装し、アプリケーションのさまざまな側面を分離します。表示ロジック、入力ロジック、ビジネスロジックなど、それぞれ異なるロジック要素を分離することは、一般に優れたアーキテクチャの実践とされています。この関心事の分離を正しく実装すれば、たとえばコードの重複を減らし、同じモデルに対して複数のビューを利用できます。

Spring MVCはSpringフレームワークの一部で、Java Webアプリケーションの構築に特化しています。Tomcatのような別のWebサーバーを使うスタンドアロンアプリケーションとしても、Spring Bootアプリケーションとしても利用できます。

この記事では、Tomcatサーバーで動作するJSP(Java Server Pages)Webページを備えたSpring MVCアプリケーションを作成しました。作成したコードは非常に基本的でシンプルです。コードは問題なく動作しますが、セキュリティに関するミスもいくつかありました。Javaの静的コード解析を使ってSpring MVCアプリケーション内のミスを検出し、修正する方法を見ていきましょう。

Spring MVCを使ったJavaアプリケーション

作成したSpring MVCのJavaアプリケーションは、とてもシンプルです。最新に近いバージョンのspring-web-mvcを使用したJava 11ベースのアプリケーションです。Model-View-Controllerパターンに沿って実装されており、シンプルなJSPページを通じてユーザーとやり取りします。このサンプルアプリケーションはGitHubで確認でき、mvn tomcat7:runを使って実行できます。

アプリケーションの基本的な機能は次のとおりです。

  • ファイルをフォルダーにアップロードする

  • ファイルをアップロードして解凍する

  • アップロードしたファイルを一覧表示する

  • メッセージボードにメッセージを書き込む

  • すべてのメッセージを一覧表示する

  • 特定のメッセージを検索する。

依存関係は必要最小限に抑えました。負荷の高い処理には定評のあるライブラリを使うこともできますが、ビジネスロジックはすべて自分で書きました。springweb-mvcに加えて、次のライブラリを使用しています。

  • ファイルのアップロードに使うcommons-fileupload

  • JSPファイル内のロジックに使うjstl

  • メッセージ用のインメモリデータベースh2

このアプリケーションにセキュリティ上のコードの問題がいくつかあることは分かっています。新しいSnyk Codeを試して、作り込んだコードの脆弱性をJava静的コード解析でどれだけ効果的に検出できるか見てみましょう。

Snyk Code:Java静的コード解析ツール

Snyk Codeは、Javaを含む複数の言語で、脆弱なコード構造の検出に特化したSnykの新製品です。Snyk CodeのJavaコード解析は、現在使用しているSpring MVCなどの主要なフレームワークにも対応しています。Snyk Codeは静的アプリケーションセキュリティテスト(SAST)ツールです。SASTは主に情報セキュリティの分野で使われる用語ですが、その名のとおり、Javaコードを静的に解析して、潜在的なセキュリティ脆弱性を探します。Snyk Codeは機械学習を活用し、開発者にとって使いやすく、コード内の脆弱性を非常に速く見つけられる方法を提供します。この記事では、SnykとのGitHubインテグレーションを使ってSnyk Codeを活用します。

注:現在、Snyk Codeの早期提供版を使用しています。一般提供はおそらく4月に開始される予定です。

Snyk CodeでSpring MVCのJavaアプリケーションをスキャンする

Snykアカウントの設定でSnyk Codeを有効にしました。有効化が完了すると、以降インポートするすべてのリポジトリがSnyk Codeによってスキャンされます。つまり、Snykがコードを積極的に検査することを許可することになります。脆弱な依存関係を探すためにSnyk Open Sourceだけを使う場合、これは必要ありません。その場合は、pom.xmlやbuild.gradleなどのマニフェストファイルを読み取るだけで済みます。

Snyk Codeが選択され、トグルで有効になっているSnyk Settingsページ。「Save changes」ボタンも表示

Spring MVCのJavaアプリケーションが含まれるGitHubリポジトリをインポートすると、すぐにSnyk Codeが動作し、Javaコード解析でセキュリティ上の問題が検出されたことが分かりました。

ファイルアップロードのロジックに関連するパストラバーサルの問題がいくつか見つかりました。また、Snyk Codeは複数のSQLインジェクション脆弱性、Cookieに関する問題をいくつか検出し、ハードコードされた認証情報も見つけました。そのうちいくつかを簡単に見てみましょう。

ファイルアップロードにおけるパストラバーサル脆弱性

Spring MVCアプリケーションでファイルをアップロードする際、受信したファイルをサニタイズしていないことがSnyk Codeによって検出されました。検証せずにファイルをそのままファイルシステムに書き込むと、パストラバーサルが可能になります。攻撃者が、ファイル名が../../../../../dir/file.xと評価されるようなPOSTリクエストを細工すると、アプリケーションの当初の範囲を抜け出して、その外部にファイルを書き込めてしまいます。既存のファイルを上書きされる可能性もあります。

UploadController.javaのFiles.writeに未サニタイズのHTTP入力が流れ込んでいることを示す、Snyk Codeのパストラバーサルレポート

Zip Slipによるパストラバーサル脆弱性

Spring MVCアプリケーションでZipファイルをアップロードして解凍する際にも、同様のパストラバーサルの問題が見つかりました。Zipファイル内のファイル名をサニタイズせずに、ファイルシステム上にファイルを作成しています。以下のようなZipファイルを使うと、アプリケーションの範囲外にファイルを作成したり、上書きしたりできます。

-rw-r--r--  18-Apr-15 23:04 good.txt
-rwxrwxrwx  18-Jun-03 17:06 ../../../../../../../../../../../../dir/file.x

Zipファイル内で発生するこの種のパストラバーサルは、Zip Slip脆弱性と呼ばれます。過去には、多くのZip解凍ライブラリにこのセキュリティ脆弱性が含まれていました。脆弱なライブラリを検出できるよう、依存関係をSnyk Open Sourceでスキャンすることも忘れないでください。

脆弱性の説明と、データフローがハイライトされたJavaのUploadController.javaコードを表示するSnyk Codeのパストラバーサル画面

メッセージ検索時のSQLインジェクション脆弱性

このSpring MVC Javaアプリケーション用に作成したメッセージリポジトリでは、指定されたパラメーターを使って検索クエリを手動で作成しています。下のスクリーンショットのとおり、クエリのパラメーター化は行っていません。クエリをパラメーター化すると、パラメーターを実際のクエリ文字列から分離できます。たとえば、パラメーターを特定の型にバインドすることで、検証やサニタイズが可能です。現在の実装では、パラメーターを既存のクエリリテラルに連結して実行しているだけです。そのため、SQLクエリを乗っ取られる可能性があります。

次の検索パラメーターを試してください。'; UPDATE message SET text = 'EVIL。元のクエリから抜け出し、すべてのメッセージを更新する新しいステートメントを実行しています。これは望ましくない動作でしょう。幸い、Snyk Codeのおかげでこの脆弱性を見つけられました。

SnykのSQLインジェクションレポート。サニタイズされていないHTTP入力がJavaのexecuteQuery呼び出しに渡される様子と、脆弱なコードが強調表示されています。

Javaコード解析で見つかったその他の脆弱性

Snykは、危険につながる可能性のある問題もいくつか検出しました。たとえば、ユーザー名やパスワードを含むデータベースの接続プロパティを、リポジトリにハードコードしています。Snyk Codeはこれを避けるよう推奨しており、その指摘は妥当です。

セキュリティスキャンにより、Javaコード内にハードコードされたデータベース認証情報が検出され、DB_URL、USER、PASSを使った接続呼び出しが表示されています。

Snyk Codeは、設定しているCookieの問題も検出しました。Spring MVCのWebアプリケーションなので、ユーザーIDを保存するための便利なCookieをクライアントシステムに設定しています。しかし、このCookieの有効期間は1年です。Cookieに機密情報を保存する場合、有効期間(maxAge)を長く設定するのは賢明ではありません。Cookieで一時的にデータを保存するなら、有効期間を短く設定すべきです。Snyk Codeがこの点を指摘するのには、もっともな理由があります。

セッション有効期限の不足に関するセキュリティ上の指摘を示す、CookieのMaxAgeを1年に設定したSpring MVCのCookieUtil.javaコードスニペット。

まとめ

Spring MVCを使ってJavaでシンプルなWebアプリケーションを作成するだけでも、さまざまな問題が発生する可能性があります。このデモアプリケーションでSnyk Codeが見つけた問題をすべて取り上げたわけではありません。残りはぜひご自身で確認してみてください。

ビジネスロジックをすべて自分で作成すると、セキュリティ上の問題が入り込む可能性があります。同じ目的を達成するのに役立つ、よくメンテナンスされたライブラリがあることを知っておきましょう。Springフレームワークの優れた例として、データベースへのクエリを支援するSpring Dataライブラリがあります。外部ライブラリを利用する際は、脆弱なライブラリを取り込まないように、Snyk Open Sourceでスキャンしてください。それでも、自分で書いたJavaコードにセキュリティ上の問題が入り込むのは簡単で、誰にでも起こり得ます。コードレビューでこうした脆弱性を見つけるのは困難です。幸い、Snyk Codeのような優れたJava静的コード解析ツールが、その発見を支援してくれます。

最先端のインテリジェンスでコードを保護

わずか30分で、Snyk CodeのSAST機能を幅広くご紹介します。