#15 JWT
国際情勢の影響もあってか、サイバー攻撃が勢いを増しているようです。つい先日も、国内で大企業のサプライチェーンが攻撃を受け、多大な被害をもたらしました。
鎖の強さは、一番弱い輪によって決まる
という格言にもあるように、システム上のたった1つの欠陥が全体に大きな影響を及ぼす例は少なくありません。
境界防御なのか、ゼロトラストネットワークなのか、防御戦略はいろいろと考えられますが、セキュリティに欠かせないトピックの一つは、やはり認証技術でしょう。
JWTは、そんな認証技術の1つとして挙げられます。最近たまに見ますが、扱ったことはなかったので、少し調べてみました。
目標
JWTについて理解を深める。
脆弱性なども見つかっているようなので、まとめてみます。
JWTとは
Json Web Token の略称で、発音は「JOT」となるそうです。特別なトークンを使い、サーバ側で情報を保持せずログインのような認証機能を実装できます。また、電子署名を使用することで改竄を検知することもできます。
jwt.ioで、実際にトークンを発行できます。
//JWTは以下のような形式
< header(base64) >.< payload(base64) >.< signature >
//header JWTの形式を定義する
{
"alg" : "< signature algorithm>",
"typ" : "JWT"
}
//payload 認証情報などを格納する
{
"id" : "1234",
"name" : "tkusa",
}
//signature 電子署名
{
//HMACSHA256など
}
以上のように、トークンに必要な情報を全て格納することで、サーバ側でDBなどを参照せず認証を実現できます。従来のセッションによる認証に対して、ステートレスな認証方法といえるでしょう。電子署名で改竄を検知することで、不正な認証を防ぐことができます。実際に、APIの認証に使われている例をみたことがあります。
認証をシンプルに実装できるという利点がある一方、気をつけなければいけない点もあります。まず、トークンはクライアント側に保存されるため、中身は簡単に見えてしまいます。ここに機微な情報を保存する設計は避けるべきでしょう。電子署名があるため改竄はできないものの、どのような情報が認証に使われるかはわかります。管理者ユーザーを、「is_admin」のようなフラグで判別している場合は、攻撃の標的にされてしまうかもしれません。
脆弱性
加えて、JWTには既知の脆弱性があり、jwt_toolsのような攻撃用ツールもあります。当ツールのGithub上に「JWT Attack Playbook」として脆弱性診断で試すべき項目がまとめられています。以下、攻撃に使われそうな脆弱性についてです。
1. alg : None 攻撃
JWTにおいて、トークンの改竄を検知するためには、電子署名アルゴリズムを指定するための"alg"の値を適切にチェックする必要があります。ここのチェックをしていないと、電子署名の検証を潜り抜け、トークンの内容を書き換えられてしまう可能性があります。algの値に"None"を指定すると電子署名の検証が行われず、認証が成功してしまいます。
2. RSA -> HMAC攻撃
電子署名アルゴリズムが公開鍵方式「RSA」である場合、こちらも"alg"を変更することで攻撃が成功してしまいます。まずalgの値を共通鍵方式である「HMACSHA」に変更します。公開鍵は厳重に管理されていない場合が多いため、簡単に取得でき、これを共通鍵として使うことでトークンの書き換えができてしまいます。
3. ブルートフォース攻撃
共通鍵として使われる値が十分に複雑でない場合、総当たりで簡単に破れてしまいます。John The RipperやHashcatのようなツールを使えば、ほんの数分でパスワードが割れてしまうこともありえます。
その他、headerに使われるkidという値を使ってディレクトリトラバーサルやRCEができる例も上記のPlaybookで紹介されています。
まとめ
JWTは、簡単に実装できる分、設計に気をつけないと脆弱性を作り込んでしまう点が少し扱いにくいかもしれません。上で紹介した脆弱性は最新版のライブラリでは修正されているようですが、やはり、実装次第では攻撃の足場になってしまうかもしれません。
認証技術としては興味深いので、さらなる改良と普及に期待します。
EOF