「鍵が開いているのに気づかない?」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. 「通信の中身は誰でも書き換えられる」という前提で実装する。
セキュリティは、最初から完璧を目指す必要はありません。今日、この「アルゴリズムの固定」という知識を身につけたあなたは、もう一つ上のレベルのエンジニアに近づきました。一歩ずつ、安全なアプリケーションを作っていきましょう!
もし何か疑問があれば、いつでも聞いてくださいね。一緒に泥臭く、かつスマートに守っていきましょう。

コメント