【入門編】JWTの署名アルゴリズム「none」脆弱性と検証時のアルゴリズム固定 – アプリケーションセキュリティ & 安全な開発防御ガイド

「鍵が開いているのに気づかない?」JWTのアルゴリズム「none」脆弱性から身を守る方法

こんにちは!セキュリティの世界へようこそ。日々、脆弱性診断やインシデント対応の現場に立っていると、「なぜこんな単純なミスが?」と思うような穴が、意外と大きな被害を生んでいることに気づかされます。

今日は、Webアプリケーションの認証でよく使われる「JWT(JSON Web Token)」に潜む、ちょっと恐ろしい「none脆弱性」についてお話しします。難しそうに聞こえますか?大丈夫、身近な例えで一緒に紐解いていきましょう。

1. まずはJWTを「玄関の通行証」に例えてみよう

JWTは、Webサイトで「私はログイン済みのユーザーですよ」と証明するための、いわば「通行証」のようなものです。

この通行証には、主に3つのパーツがあります。
1. ヘッダー:通行証の種類や、どんな鍵(アルゴリズム)で封印しているかが書かれている。
2. ペイロード:あなたの名前やIDなど、中身の情報。
3. 署名(シグネチャー)ここが超重要! サーバーが「これは偽物じゃないよ」と保証するために押すハンコ。

通常、サーバーはこの「署名」を確認して、「おっ、確かにうちのサーバーが発行したハンコだな」と判断して中を通します。

2. なぜ「none」という脆弱性が生まれるのか?

さて、ここからが攻撃者の狙い目です。もし、通行証のヘッダーにこう書かれていたらどうでしょう?

  • 「署名アルゴリズム:`none`(なし)」

これは、「この通行証にはハンコを押していませんよ。だから確認しなくていいですよ」という意味になってしまいます。

泥棒(攻撃者)は、このヘッダーを書き換えて、ペイロード(中身)を「ユーザーID:admin(管理者)」に改ざんします。そして、「署名はなし!」というルールをサーバーに信じ込ませるのです。

もしサーバー側が「ヘッダーで指定されたアルゴリズムをそのまま信用して確認する」という甘い設定になっていたら……サーバーは「あ、署名なしでいいんだね、じゃあ中身を確認して通そう!」と、いとも簡単に玄関を開けてしまいます。これが「none脆弱性」の正体です。

3. 防御の鉄則:アルゴリズムを「固定」する

この攻撃を防ぐのは非常にシンプルです。「サーバー側が、期待するアルゴリズムを強制的に固定すること」です。

「うちは絶対にHS256という鍵を使う!」と決めておけば、たとえ攻撃者が「アルゴリズムはnoneだ!」と嘘のヘッダーを送ってきても、サーバー側が「いや、うちはHS256以外は受け付けないよ」と突っぱねることができます。

コードでの実装例(Node.js / jsonwebtokenライブラリの例)

多くのライブラリでは、検証時にアルゴリズムを指定するオプションが用意されています。

const jwt = require(‘jsonwebtoken’);

// 悪い例:受け取ったJWTのヘッダーをそのまま信じてしまう
// jwt.verify(token, secret);

// 良い例:期待するアルゴリズム(HS256)を明示的に指定する
try {
const decoded = jwt.verify(token, ‘あなたの秘密の鍵’, {
algorithms: [‘HS256’] // ここで「HS256以外は絶対に認めない!」と設定
});
console.log(“認証成功:”, decoded);
} catch (err) {
console.error(“認証失敗:不正なトークン、もしくはアルゴリズムが違います”);
}

このたった1行の`algorithms`指定があるだけで、`none`攻撃は完全に封じ込めることができます。

4. セキュリティ担当者からのアドバイス

開発現場でよくあるのは、「とりあえずライブラリのデフォルト設定で動かした」というケースです。セキュリティとは、「便利さ」と「厳格さ」のバランスです。

  • ライブラリのドキュメントを読み込む: 使っているライブラリが「デフォルトで署名を検証するか?」を必ず確認してください。
  • 「信用しない」を前提にする: 通信の相手(ブラウザからのリクエスト)は、常に悪意のある改ざんをしてくる可能性がある、と考えておきましょう。
  • 最新のライブラリを使う: セキュリティ関連のライブラリは、脆弱性が見つかるとすぐに修正版が出ます。定期的なアップデートは、家で言えば「鍵の交換」と同じです。

まとめ:今日からできること

1. JWTを使う際は、必ず`algorithms`を指定する。
2. `none`アルゴリズムを許可しない構成にする。
3. 「通信の中身は誰でも書き換えられる」という前提で実装する。

セキュリティは、最初から完璧を目指す必要はありません。今日、この「アルゴリズムの固定」という知識を身につけたあなたは、もう一つ上のレベルのエンジニアに近づきました。一歩ずつ、安全なアプリケーションを作っていきましょう!

もし何か疑問があれば、いつでも聞いてくださいね。一緒に泥臭く、かつスマートに守っていきましょう。

コメント

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