JWTをハックしてみる

はじめに
こんにちは!
株式会社BTMの畑です。
今回はJWTの取得から、中身のチェック、権限をハッキングして改竄するところまでをやってみます。
本記事で紹介する手法は、セキュリティ検証を目的として自分自身が管理するWebシステムに対してのみ実施してください。他者のシステムや許可を得ていない環境に対して行うことは不正アクセス禁止法等の法律に違反し、犯罪となります。絶対に行わないでください。
そもそもJWTって?
JWTとは「JSON Web Token」の略で、情報をJSON形式で安全にやり取りするための標準規格です。RFC7519で定義されています。主にユーザー認証やセッション管理に使用されます。
↓実際のJWTはこのような見た目で、パッと見は何か分からない見た目になっています。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtZSI6ImJ0bV9oYXRhIiwiaWF0IjoxMjM0NTY3ODkwfQ.ynJxQmc0Ik0Y9yu7CPwX82Rn0rCVs9i4A8T8x6wLvMA
JWTの構成
- ヘッダー (Header)
トークンのタイプと使用している署名アルゴリズムを指定 - ペイロード (Payload)
実際に送信したいデータ(クレーム)を含む - 署名 (Signature)
トークンが改竄されていないことを確認するための署名
JWTの一般的な使用場面
- ユーザー認証:ログイン後のセッション管理に使用
- シングルサインオン(SSO):複数サービス間での共通認証
- APIアクセストークン:RESTful APIのアクセス制御やクライアント認証
JWTの利点
- ステートレス認証が可能(サーバーでセッション保持不要)
- スケーラビリティが高い(サーバー間の状態共有不要)
- クロスドメインでの認証が容易
ただし、セキュリティ面では適切な実装と運用が重要になります。署名の検証や有効期限設定、適切な暗号化アルゴリズム選択が不可欠です。
JWTをハッキングしてみる
事前準備
簡単に動作確認できるようにPHPの処理を作成しました。
jwt-demo/
├── index.php # ログイン処理
├── admin.php # 管理ページ
└── functions.php # 共通関数
主な機能:
- ユーザー名とパスワードでログイン認証
- 認証成功時に対象アカウントの権限ロールをJWTで返す
- 管理ページアクセス時にJWTのロールを確認し、権限に応じて表示/非表示
リポジトリ:github.com/BTM-GitHub-organization/jwt-demo
今回の確認用に最低限の実装となっています。そのまま利用すると脆弱性等のリスクがありますのでご注意ください。
まずはJWTを取得します
一般ユーザー(user / user123)でログイン:
http://localhost/jwt-demo/index.php
返ってきたJWT:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqd3QtZGVtbyIsImlhdCI6MTczNDg1OTM5OSwiZXhwIjoxNzM0ODYyOTk5LCJ1c2VybmFtZSI6InVzZXIiLCJyb2xlIjoidXNlciJ9.GDZ5586GkZRLiZwNEBi8O3aRyKBzOsGXmyrBq_bB214
管理者ページにアクセスしてみる
AuthorizationヘッダーにJWTをセットしてPOST:
http://localhost/jwt-demo/admin.php
結果:
{"error":"Forbidden"}
JWT中のロールを書き換えても同様にForbiddenとなります。
シークレットキーをハッキング
署名アルゴリズムにHS256
が使われているため、シークレットキーが必要です。キーを総当たり解析するために John the Ripper を使用します。
パスワード管理やセキュリティ検証のためのツール使用は、自社システムや許可を得た環境のみに限定してください。
PS C:\john-1.9.0-jumbo-1-win64\run> john.exe jwt.txt
Using default input encoding: UTF-8
Loaded 1 password hash (HMAC-SHA256 [password is key, SHA256 256/256 AVX2 8x])
Will run 16 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Proceeding with wordlist:/run/password.lst, rules:Wordlist
demo (?)
Session completed
AI解析の進歩により解析スピードが高速化。複雑かつ長いシークレットキーと適切な有効期限設定が重要です。
特定されたキーでJWTを改竄し、再度管理者ページへ:
{"message":"Welcome to the admin page!"}
まとめ
JWTを使用する際の注意点:
- 機密情報の扱い
ペイロードは暗号化されないため、機密情報は含めない。 - セキュアな鍵を設定
ランダムで長いシークレットキーを使用(32文字以上推奨)。 - 有効期限の設定
適切な有効期限を設定し、長期間の使用を避ける。
おわりに
今回はJWTをハッキングして仕組みを確認しました。適切な実装・運用で安全かつ効率的な認証・認可を実現しましょう。
株式会社BTMではエンジニア採用をしております。ご興味がある方はぜひコチラをご覧ください。
-
SNS
-
投稿日
-
カテゴリー
BTM Useful