Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】The Definitive Guide to JWT Security in 2026: HS256 vs RS256 vs ES256, The alg: none Exploit, kid Parameter Attacks, and Token

2026年10月23日に「Dev.to」が公開したITニュース「The Definitive Guide to JWT Security in 2026: HS256 vs RS256 vs ES256, The alg: none Exploit, kid Parameter Attacks, and Token」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

JWTは認証に広く使われるが、設定ミスで多くの脆弱性を生む。`alg: none`攻撃やアルゴリズム混同、`kid`パラメータ悪用、弱い鍵、LocalStorageへの保存は特に危険だ。HS256/RS256/ES256の違いを理解し、非対称署名とリフレッシュトークンローテーションで安全性を確保しよう。

ITニュース解説

JSON Web Tokens (JWT) は、マイクロサービス間の認証、シングルサインオン、OAuth 2.0やOpenID Connectの認証フローに不可欠な、ステートレスな認証情報の業界標準である。その広範な利用にもかかわらず、JWTはしばしば誤設定され、現代のアプリケーションセキュリティにおける脆弱性の原因となることが多い。システムエンジニアを目指す者にとって、JWTの仕組みとセキュリティ上の注意点を深く理解することは極めて重要である。

JWTは、URLセーフな文字列として、ヘッダー、ペイロード、署名の三つの部分から構成される。これらはそれぞれBase64URLエンコードされ、ピリオドで区切られて連結されている。

まず、ヘッダーには、トークンの署名にどの暗号化アルゴリズムが使われたか(alg)、トークンのタイプ(typ)、そして鍵の識別子(kid)など、トークンを解釈し検証するためのメタデータが含まれる。例えば、「alg」に「HS256」と指定されることで、署名の検証方法が示される。

次に、ペイロードには、トークンの発行者(iss)、対象者(sub)、受信者(aud)、有効期限(exp)、発行時刻(iat)といった、ユーザーやセッションに関する情報(クレーム)が含まれる。JWTは署名によって改ざんを検出できるものの、暗号化はされていないため、ペイロードの内容は誰でも簡単にデコードして閲覧できる。このため、パスワードや個人情報などの機密データをペイロードに直接格納することは絶対に避けるべきだ。

最後に、署名は、エンコードされたヘッダーとペイロードを結合したデータと、特定の秘密鍵を用いて暗号学的に生成される。この署名により、トークンが正当な発行元によって発行され、その内容が途中で一切改ざんされていないことを検証できる。

JWTの署名に用いられるアルゴリズムには、HS256、RS256、ES256、EdDSAなどがある。HS256は対称鍵暗号方式であり、発行と検証に同じ秘密鍵を使用する。高速だが、検証側のサービス全てが秘密鍵を持つため、いずれかのサービスが侵害されると、攻撃者にトークンを偽造されるリスクがある。対照的に、RS256、ES256、EdDSAは非対称鍵暗号方式を採用する。発行サーバーは秘密鍵で署名し、検証サービスは公開鍵で検証する。公開鍵は公開されても安全であるため、検証サービスが攻撃されてもトークンの偽造は不可能である。このため、複数のサービスがトークンを検証する分散システムにおいては、非対称鍵暗号方式がセキュリティの観点から強く推奨される。特にES256やEdDSAは、RS256に比べて効率が良く、コンパクトな署名サイズと高いセキュリティ強度を両立させる最新の選択肢だ。

JWTを安全に利用するためには、主要な攻撃手法とその対策を理解することが不可欠である。

一つ目は「alg: none」脆弱性だ。不適切な検証ライブラリは、トークンヘッダーの「alg」が「none」である場合に署名をチェックせず、トークンを有効と判断してしまうことがある。攻撃者は署名部分を削除し、「alg: none」の偽造トークンを作成することで、認証を迂回できてしまう。この脆弱性への対策は、検証時に許可するアルゴリズムを「RS256」や「ES256」のように明示的にホワイトリスト形式で指定し、「none」の使用を拒否することである。

二つ目は、アルゴリズム混乱攻撃である。非対称鍵(RS256など)を使用するシステムで、攻撃者は公開されているサーバーの公開鍵を入手し、JWTヘッダーを「alg: HS256」に書き換える。そして、入手した公開鍵の文字列をHMAC-SHA256の秘密鍵として利用してトークンに署名する。脆弱なサーバーが、トークンヘッダーの指示に従いHS256として検証しようとする際、誤って公開鍵をHMACの秘密鍵として使用してしまうと、攻撃者の偽造したトークンが有効と判断される。対策として、トークンヘッダーの「alg」と、実際に使用する鍵の形式(対称鍵か非対称鍵か)が厳密に一致するかを検証する必要がある。

三つ目は「kid」パラメータインジェクションだ。「kid」(Key ID)は、システムが複数の検証鍵を持つ場合に、どの鍵を使用すべきかを示す識別子である。サーバーが「kid」の値を直接ファイルパスやデータベースクエリに利用するような脆弱な実装の場合、攻撃者は「kid」に不正なパスを注入して意図しないファイルを読み込ませたり、SQLインジェクション攻撃を仕掛けたりすることが可能になる。これにより、サーバーが空の秘密鍵で署名されたトークンを検証したり、攻撃者が指定した秘密鍵を取得してしまったりする。対策としては、「kid」の値を信頼できない入力として扱い、厳格な正規表現で検証するか、ファイルシステムやデータベースではなく、プログラム内の安全なマップ構造から鍵を検索するべきである。

四つ目は、弱いHMAC秘密鍵とオフライン総当たり攻撃である。HS256のような対称鍵方式では、秘密鍵が推測されやすい文字列の場合、攻撃者は傍受したJWTを利用してオフラインで高速な総当たり攻撃を行うことで秘密鍵を解読する。解読された秘密鍵を使って、攻撃者は任意の有効なJWTを生成できてしまう。このリスクを避けるためには、十分なエントロピーを持つ、ランダムに生成された256ビット以上の長さの秘密鍵を使用する必要がある。

五つ目は、認証トークンの保存場所に関する脆弱性である。ブラウザのlocalStorageにアクセストークンを保存することは、Cross-Site Scripting (XSS) 攻撃に対して非常に脆弱だ。もしウェブサイトにXSS脆弱性があれば、攻撃者はJavaScriptを用いてlocalStorageから簡単にトークンを盗み出し、ユーザーのセッションを乗っ取ることができる。最も安全な保存方法は、認証トークンをHttpOnly; Secure; SameSite=Strict属性を持つクッキーに保存することである。HttpOnlyはJavaScriptからのアクセスを禁止し、SecureはHTTPS通信のみでの送信を強制し、SameSite=Strictは異なるオリジンからのクッキー送信をブロックすることで、XSSやCSRF(クロスサイトリクエストフォージェリ)攻撃への耐性を大幅に向上させる。

これらの攻撃に対処し、さらに堅牢な認証システムを構築するために、リフレッシュトークンローテーション(RTR)というアーキテクチャが推奨される。アクセストークンの有効期限は5分から15分といった短期間に設定し、もしトークンが漏洩しても悪用できる時間を限定する。一方、より長期間有効なリフレッシュトークンは、有効期限が切れたアクセストークンを再発行するために用いられる。リフレッシュトークンローテーションでは、リフレッシュトークンが一度使用されると、古いものは無効化され、新しいリフレッシュトークンが発行される。もし攻撃者が古いリフレッシュトークンを傍受し、それがすでに正当なユーザーによって使用されていた場合、システムはこれをトークン盗難の兆候と判断し、そのユーザーの全てのセッションを即座に無効化して再認証を強制する。これにより、不正アクセスを迅速に検知し、被害を最小限に抑えることが可能となる。

本番環境でJWTを使用する際には、以下のセキュリティチェックリストを確認することが重要である。許可するアルゴリズムを明示的に指定し、トークンヘッダーが検証アルゴリズムを決定することを防ぐ。アクセストークンの有効期限を短く設定する。発行者(iss)、対象者(aud)、有効期限(exp)、有効開始時間(nbf)などの必須クレームを常に検証する。パスワードやAPIキーなどの機密情報をトークンペイロードに格納しない。そして、トークンはHttpOnly; Secure; SameSite=Strict属性のクッキーに保存し、鍵のローテーションを適切に実装することが求められる。

最後に、JWT、JWS、JWEは関連するが異なる概念だ。JWTはJSON形式でクレームを表現する汎用的なフォーマットを指す。JWS(JSON Web Signature)は署名されたJWTのことで、内容は平文で読めるが、改ざんを検出できるため、一般的に「JWT」という言葉で指されるのはこのJWSである。JWE(JSON Web Encryption)は暗号化されたJWTであり、復号鍵なしには内容を読み取ることができないため、高い機密性が必要な場面で利用される。これらの違いを理解し、要件に応じた適切な選択をすることが、安全なシステム構築に繋がる。

関連コンテンツ

関連IT用語

関連ITニュース