【入門編】JWTのクレーム検証(exp, nbf, aud)の重要性と実装 – アプリケーションセキュリティ & 安全な開発防御ガイド

JWTの「鍵」をかけ忘れていませんか?なりすましを防ぐための必須知識

こんにちは。セキュリティの世界で長く泥臭い現場を見てきた私から、今日は「JWT(JSON Web Token)」という、現代のWebアプリケーションに欠かせない「デジタルな通行手形」についてお話しします。

JWTは便利ですが、扱い方を間違えると、まるで「鍵がかかっていない玄関に、誰でも入れる合鍵を置きっぱなしにしている」ような状態になってしまいます。

今回は、新人の開発者の方にもわかるように、身近な例えを交えて「なぜ検証が必要なのか」を紐解いていきましょう。

—

そもそもJWTって何者?

JWTは、サーバーが「この人はログイン済みですよ」と証明するために発行する小さなデータ片です。身近な例で言えば、「ホテルのルームキー」のようなものですね。

フロントエンド(あなたのPC)はこのキーを提示することで、「私は宿泊客です!」と証明し、サーバー内の部屋(管理画面や個人情報)に入ることができます。

しかし、もしこのキーに「いつまで有効か」「誰のための鍵か」という情報が書かれていなかったらどうなるでしょう? 泥棒は拾った鍵を、10年後でも、隣のホテルの部屋でも使えてしまいますよね。これがJWTの検証を怠ることで起きる「なりすまし」の正体です。

—

泥棒を寄せ付けないための「3つのチェック項目」

JWTには、身元を証明するための「クレーム」と呼ばれる情報が含まれています。特に重要なのが以下の3つです。これをチェックしないのは、玄関の鍵を開けっ放しにするのと同じです。

1. exp (Expiration Time / 有効期限)

  • 意味: 「この鍵はいつまで使えるか」という期限。
  • リスク: チェックしないと、盗まれた古い鍵がずっと有効なままになります。

2. nbf (Not Before / 開始時刻)

  • 意味: 「この鍵はいつから使えるか」。
  • リスク: 未来の日付が設定されているのに今すぐ使えてしまうと、不正な先走りを許すことになります。

3. aud (Audience / 対象者)

  • 意味: 「この鍵はどこのサービス向けのものか」。
  • リスク: 悪意のあるサイトで発行された鍵を、あなたのシステムで受け入れてしまう可能性があります。

—

実装の現場:ライブラリに丸投げしない「心構え」

「ライブラリを使えば自動でやってくれるんでしょ?」と思われるかもしれません。確かにその通りですが、設定を有効にしていないライブラリは、鍵のついていない金庫と同じです。

多くのライブラリでは、検証関数にオプションを渡すことで、これらのチェックを強制します。Node.jsの jsonwebtoken を使った例を見てみましょう。

const jwt = require(‘jsonwebtoken’);

// サーバーに保存してある秘密鍵(これが漏れると全てが台無しです!)
const secretKey = ‘super-secret-key’;

try {
// ここで検証を行います
const decoded = jwt.verify(token, secretKey, {
// 1. 有効期限(exp)のチェックを有効化
ignoreExpiration: false,
// 2. このトークンは誰向けか?(aud)
audience: ‘my-awesome-app’,
// 3. 発行者は誰か?(iss) ※おまけで検証しておくとより安全
issuer: ‘auth-server’
});

console.log(‘認証成功!’, decoded);
} catch (err) {
// 検証に失敗した場合は、即座にアクセスを遮断します
// 「鍵が無効です」というエラーを返しましょう
console.error(‘なりすましの疑い、または期限切れです:’, err.message);
}

このコードのポイント

  • ignoreExpiration: false:デフォルトでオフになっていることも多いので、明示的に指定するのがプロの流儀です。
  • audience:自分のアプリ名を設定することで、「他人が作った偽の鍵」を入り口で弾くことができます。

—

最後に:セキュリティは「疑うこと」から始まる

セキュリティエンジニアとして一番怖いのは、「ライブラリがやってくれているだろう」という思い込みです。

  • 鍵(秘密鍵)は絶対に漏らさない
  • 期限切れの鍵は容赦なく捨てる
  • 自分のサービス宛てでない鍵は受け取らない

この3つを徹底するだけで、あなたのアプリケーションは格段に強固になります。

最初は難しく感じるかもしれませんが、一歩ずつ、コードの裏側にある「泥棒の視点」を意識してみてください。そうすれば、自然と「ここはチェックしておかないと怖いな」という直感が働くようになります。

さあ、今日のコードから verify の設定を見直してみましょう。あなたのサービスを守る鍵を、しっかりと強固なものにしてくださいね!応援しています。

コメント

タイトルとURLをコピーしました