Skip to main content

Spring Bootのセキュリティに関する10のベストプラクティス

著者

Matt Raible

Spring Boot Security Best Practices small

2018年8月16日

0 分で読めます

Spring Bootを使っているけれど、セキュリティ対策をどこから始めればよいかわからない?もう心配はいりません。このチートシートでは、開発者やメンテナーがSpring Bootのセキュリティを強化するためのベストプラクティスをご紹介します。

Spring Bootは、Springアプリケーションの開発を大幅に簡素化するため、Javaエコシステムで最も広く使われているフレームワークの一つです。だからこそ、Spring Bootアプリケーション全体のセキュリティ態勢を強化することが大切です。そのための方法を、私たちがお手伝いします。

この記事は、Java ChampionでありOktaのDeveloper Advocateでもある、同僚のMatt Raibleと共に、もともとブログ記事として詳しく執筆したものです。私たちはどちらもセキュリティ業界の企業で働き、Javaを愛し、開発者がより安全なアプリケーションを作れるよう支援したいと考えています。そこで、Spring Bootセキュリティの見やすいチートシートを作ることにしました。

前置きはここまでにして、Spring Bootセキュリティのベストプラクティスを見ていきましょう。元の記事はより詳しい内容で、Oktaのブログからご覧いただけます。

Spring Bootのセキュリティとは?

Spring Bootのセキュリティが指す内容はさまざまです。一般的には、Spring Bootセキュリティのスターター依存関係を追加し、Spring SecurityフレームワークをSpring BootのWebアプリケーションに組み込むことを意味します。Spring Securityは認証とアクセス制御のフレームワークで、Spring Bootアプリケーションに簡単に導入できます。一方、Spring Bootのセキュリティは、Spring Securityフレームワークを追加するだけにとどまりません。このチートシートでは、Spring Bootのセキュリティをより広く捉え、Spring Bootで作成したアプリケーションを保護する方法を解説します。

Spring Bootセキュリティのベストプラクティス

以下の厳選リストでは、Spring Bootアプリケーションの認証と認可にSpring Securityを導入するだけでなく、より包括的なSpring Bootセキュリティ戦略に焦点を当て、次のトピックを取り上げます。

  1. 本番環境でHTTPSを使用する

  2. 依存関係をテストしてSpring Bootの脆弱性を検出する

  3. CSRF対策を有効にする

  4. コンテンツセキュリティポリシーでSpring BootのXSSを防ぐ

  5. 認証にOpenID Connectを使用する

  6. パスワードをハッシュ化する

  7. 最新リリースを使用する

  8. シークレットを安全に保管する

  9. アプリを侵入テストする

  10. セキュリティチームにコードレビューを依頼する

1. 本番環境でHTTPSを使用する

かつてTLS/SSL証明書は高価で、HTTPSは遅いと考えられていました。マシンの処理速度が大幅に向上してパフォーマンスの問題が解消され、さらにLet’s Encryptが無料のTLS証明書を提供するようになりました。この2つの進歩によって状況は一変し、TLSは広く普及しました。

Spring BootアプリでHTTPSを必須にするには、WebSecurityConfigurerAdapterを拡張し、安全な接続を要求します。

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

 @Override
 protected void configure(HttpSecurity http) throws Exception {
   http.requiresChannel().requiresSecure();
 }
}

クラウドプロバイダーを利用すると、TLS証明書の管理を大幅に簡素化できます。Amazon Certificate ManagerはLet’s Encryptと同様のサービスですが、AWSのすべての製品・サービスにデフォルトで組み込まれています。完全無料のSSL証明書を発行でき、自動更新なども設定作業なしで処理されます。HerokuにもAutomated Certificate Managementがあります。

2. 依存関係をテストしてSpring Bootの脆弱性を検出する

アプリケーションが直接依存している依存関係の数を把握していない方は多いでしょう。推移的依存関係の数となれば、把握していない可能性はさらに高くなります。依存関係はアプリケーション全体の大部分を占めることが多く、Spring Bootのセキュリティ脆弱性を含む可能性もあるにもかかわらず、これはよくあることです。オープンソースの依存関係は再利用されることで被害に遭う対象が増えるため、攻撃者に狙われるケースが増えています。アプリケーションの依存関係ツリー全体に既知の脆弱性がないことを確認することが重要です。

Snykはアプリケーションのビルド成果物をテストし、既知のSpring Bootセキュリティ脆弱性を含む依存関係を検出します。ダッシュボードで、アプリケーションが使用しているパッケージに存在する脆弱性の一覧を確認できます。

3つのGitHub Mavenプロジェクトについて、高・中・低の脆弱性件数と、脆弱性のあるすべてのプロジェクトを表示するSnykダッシュボード。

さらに、セキュリティの問題を修正するためのアップグレードバージョンを提案したり、ソースコードリポジトリにプルリクエストを作成してパッチを提供したりします。またSnykは、リポジトリに今後作成されるプルリクエストもWebhook経由で自動的にテストし、新たな既知のSpring Bootセキュリティ脆弱性が持ち込まれないよう環境を保護します。

SnykはWeb UIとCLIの両方から利用できるため、CI環境に簡単に統合できます。また、脆弱性の深刻度が設定したしきい値を超えた場合にビルドを失敗させるよう設定できます。

Capture the Flagを始めよう

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

3. CSRF対策を有効にする

クロスサイトリクエストフォージェリとは、ユーザーがログイン中のアプリケーションで、意図しない操作を実行させる攻撃です。

Spring Securityには優れたCSRF対策機能があり、デフォルトで有効になっています。Spring MVCの<form:form>タグ、またはThymeleafと@EnableWebSecurityを使用している場合、CSRFトークンは非表示の入力フィールドとして自動的に追加されます。これをSpring Bootセキュリティ戦略に組み込むには、Spring Securityスターターを依存関係として追加します。

AngularやReactなどのJavaScriptフレームワークを使用している場合は、JavaScriptからCookieを読み取れるようにCookieCsrfTokenRepositoryを設定する必要があります。

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http
           .csrf()
               .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
   }
}

HTTPS経由でリクエストが行われると、Spring SecurityはsecureフラグをXSRF-TOKEN Cookieに自動的に追加します。Spring SecurityはCSRF CookieにSameSite=strictフラグを使用しませんが、Spring SessionまたはWebFluxのセッション管理を使用する場合は使用します。

4. コンテンツセキュリティポリシーでSpring BootのXSSを防ぐ

コンテンツセキュリティポリシー(CSP)は、XSS(クロスサイトスクリプティング)やデータインジェクション攻撃の緩和に役立つ、追加のセキュリティレイヤーです。有効にするには、アプリケーションがContent-Security-Policyヘッダーを返すように設定します。HTMLページで<meta http-equiv="Content-Security-Policy">タグを使用することもできます。

Spring Securityは、デフォルトで複数のセキュリティヘッダーを提供します。ただし、Spring SecurityはCSPをデフォルトでは追加しません。以下の設定を使用すると、Spring BootアプリでCSPヘッダーを有効にできます。

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.headers()
           .contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/");
   }
}

5. 認証にOpenID Connectを使用する

OpenID Connect(OIDC)は、ユーザー情報を提供するOAuth 2.0の拡張仕様です。アクセストークンに加えてIDトークンを追加し、追加情報を取得できる/userinfoエンドポイントも提供します。また、エンドポイントの検出機能と動的なクライアント登録機能も追加されます。

以下の図は、認証におけるOIDCの仕組みを示しています。

クライアント、認可サーバー、ユーザーの同意、コールバック、トークン交換を示すOIDC認可コードフローの図。

6. パスワードをハッシュ化する

パスワードを平文で保存するのは、アプリのセキュリティにとって最悪の行為の一つです。幸い、Spring Securityではデフォルトで平文パスワードは使用できません。また、対称暗号化、鍵生成、パスワードハッシュ化(パスワードエンコーディング)に使える暗号化モジュールも用意されています。

PasswordEncoderは、Spring Securityにおけるパスワードハッシュ化の主要インターフェースで、次のようになっています。

public interface PasswordEncoder {
   String encode(String rawPassword);
   boolean matches(String rawPassword, String encodedPassword);
}

Spring Securityには複数の実装があり、最もよく使われているのはBCryptPasswordEncoderとPbkdf2PasswordEncoderです。

7. 最新リリースを使用する

アプリケーションの依存関係を定期的にアップグレードする理由はいくつもあります。アップグレードを行う重要な理由の一つがセキュリティです。start.spring.ioのスターターページでは、可能な場合にSpringパッケージと依存関係の最新バージョンが使用されます。

インフラストラクチャのアップグレードは、ライブラリの作者によって後方互換性やリリース間の動作変更への配慮に差があるため、依存関係のアップグレードより影響が小さいことがよくあります。とはいえ、設定にセキュリティ脆弱性が見つかった場合の選択肢は、アップグレード、パッチ適用、または無視の3つです。アプリケーション全体の健全性を考えると、アップグレードが最も安全ですが、常に実行できるとは限りません。その場合は、Snykのようなセキュリティ専門家から入手できるパッチを適用し、パッケージの脆弱性を解消できます。もちろん脆弱性を無視する選択肢もありますが、おすすめできません。脆弱性を把握していても、直接悪用される可能性はないと考えることがあるかもしれません。しかし、現在のアプリケーションの処理フローに含まれていなくても、将来、開発者が脆弱な経路を使うコードを追加する可能性があることを忘れないでください。

8. シークレットを安全に保管する

Spring Bootのセキュリティ戦略では、データについても考える必要があります。パスワードやアクセストークンなどの機密情報は慎重に扱いましょう。こうした情報を放置したり、平文で渡したり、ローカルストレージに予測可能な形で保存したりしてはいけません。(GitHubの)履歴が幾度となく示しているように、開発者はシークレットの保管方法を十分に考えていないことがあります。

シークレットを保管し、アクセスを管理し、アプリケーションが利用するサービスの認証情報を生成することもできるVaultを使うのがよい方法です。HashiCorp Vaultを使えば、シークレットを簡単に保存できるだけでなく、さまざまな追加サービスも利用できます。LDAPなどの一般的な認証メカニズムと連携して、トークンを取得することも可能です。

興味があれば、ぜひSpring Vaultについて調べてみてください。HashiCorp Vaultの抽象化レイヤーを提供し、Springのアノテーションベースでクライアントからアクセスできるようにします。これにより、インフラストラクチャの詳細に煩わされることなく、シークレットへのアクセス、保存、失効が可能になります。以下のコード例では、アノテーションを使ってSpring Vaultからパスワードを簡単に取得する方法を示しています。

@Value("${password}")
String password;

9. アプリを侵入テストする

セキュリティツールOWASP ZAPは、稼働中のアプリケーションに対して実行時に侵入テストを行うプロキシです。GitHubでホストされている人気の高い(スター数4,000超)無料のオープンソースプロジェクトです。

OWASP ZAPは、SpiderとActive Scanという2つの方法で脆弱性を検出します。Spiderツールは、URLを起点として各レスポンスにアクセスして解析し、ハイパーリンクを特定してリストに追加します。次に、見つかったURLにアクセスして同じ処理を再帰的に続け、WebアプリケーションのURLマップを作成します。Active Scanツールは、選択したターゲットを潜在的な脆弱性のリストに照らして自動的にテストします。Webアプリケーションのどこが悪用可能かを、脆弱性の詳細とともにレポートします。

10. セキュリティチームにコードレビューを依頼する

コードレビューは、パフォーマンスの高いソフトウェア開発チームに欠かせません。Oktaでは、本番環境のコードと公式オープンソースプロジェクトのすべてについて、専門のセキュリティチームによる分析を必須としています。自社にセキュリティの専門家がいない場合でも、機密データを扱っているなら、セキュリティチームによるレビューを検討してみてはいかがでしょうか。

Spring Boot Securityチートシートをダウンロードして、目につく場所に貼っておきましょう。Spring Bootを使ってアプリケーションを開発する際に従うべきベストプラクティスを、いつでも確認できます。

よくある質問

Spring Bootにセキュリティを追加するには?

Spring BootアプリケーションにSpring Securityを追加するには、まずセキュリティのスターター依存関係を追加します。

Spring BootでSpring Securityを無効にするには?

デフォルトでは、spring-boot-starter-securityパッケージを含めるとSpring Securityが有効になります。application.propertiesファイルでSecurityAutoConfigurationを除外すれば、簡単に無効化できます。

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration

Capture the Flagを始めよう

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

続きを読む

Blog

フロンティアモデルは脆弱性を発見した。攻撃者だけがエクスプロイトチェーンを見つけた。

静的解析で欠陥は見つかりましたが、ライブ攻撃テストで侵害につながる連鎖を実証できたのは唯一でした。Evo COS、Claude Security、Claude Code Securityを比較します。

feature insights context
Blog

自律型攻撃はすでに始まっている。防御もそのスピードに追いつかなければならない。

自律型攻撃者によって、防御に使える時間は短くなっています。継続的な検出、修復、検証、予防で、セキュリティチームが攻撃に歩調を合わせる方法をご紹介します。

Blog

AIコーディングエージェントが不適切なアクセス制御を繰り返し実装する理由

AIコーディングエージェントは、コンパイルが通りレビューも通過する一方で、あるテナントのデータを別のテナントに公開してしまう認可ロジックを生成することがあります。不適切なアクセス制御が検出しにくい理由と、その防止策をご紹介します。