Pythonで、ログインの証として使うトークン(JWT)を作ったり確かめたりするライブラリ「PyJWT」に、トークンを偽造できる欠陥が見つかりました。GitHubは日本時間の10月23日未明、この勧告(GHSA-pxh4-856f-4h89)を確認済みの勧告のデータベースに載せました。深刻度はHigh(CVSS 3.1で7.4)です。CVEの番号は、10月23日の時点では付いていません。
対象は2.13.0以前で、2.14.0で直っています。2.14.0は9月11日に出ていて、勧告もそのときにPyJWTのリポジトリで公表されていました。
GitHubの勧告。PyJWT 2.13.0以前が対象で、2.14.0で修正出典: GitHub Advisory Database「GHSA-pxh4-856f-4h89」(引用)
何が起きるのか
PyJWTは、共有の鍵で署名するHS256・HS384・HS512のトークンを、JWK(鍵をJSONで表す形)で受け取った鍵で確かめられます。勧告によると、このJWKの鍵(kty=oct)の値kが空の文字列でも、PyJWTは誤りにせず、長さ0の鍵として受け取ります。
その鍵でトークンを確かめると、PyJWTは空の鍵で署名を計算し、同じく空の鍵で攻撃者が作った偽のトークンを、正しいものとして通してしまいます。攻撃者は秘密の値を知る必要がありません。手元で空の鍵で署名を作り、トークンの鍵の番号(kid)を、空の鍵のJWKに合わせるだけです。トークンの中身(だれとしてログインしているかなど)は、自由に書き換えられます。
PyJWTは2.13.0で、文字列やバイトの形で渡した空の鍵を止めるようにしていました。ところが、JWKから鍵を作る道(from_jwk)には、その止める処理が入っていませんでした。初期の設定では、短い鍵は警告(InsecureKeyLengthWarning)を出すだけで、確かめはそのまま通ります。
| 項目 |
内容 |
| 勧告 |
GHSA-pxh4-856f-4h89(CWE-347、署名の確かめの不備) |
| 深刻度 |
High(CVSS 3.1で7.4。ネットワーク越し・認証なし・攻撃の難しさは高) |
| 対象 |
PyJWT 2.13.0以前 |
| 直る版 |
2.14.0 |
| 影響する使い方 |
PyJWK、PyJWKSet、PyJWKClientで受け取った共有の鍵で、HS系の署名を確かめる |
起きる条件は「空の鍵」の設定の誤り
勧告は、確かめに使うJWKやJWKSに空の鍵が入る場面として、次を挙げています。
- 署名の秘密の値を、設定していない環境変数や、空の設定の行から読んでいて、空の値がそのままJWKSに書き出される
- 空の鍵を含むJWKSを、そのまま信用している
つまり、鍵の設定をし忘れたまま動いているアプリが狙われます。勧告は、JavaScriptのfast-jwt(CVE-2026-44351)やRubyのruby-jwt(CVE-2026-45363)でも、同じ「空の鍵を通してしまう」欠陥がライブラリの側で直されたと書いています。
勧告に載ったPyJWTのコードでは、確かめるときの設定enforce_minimum_key_lengthを有効にすると、短い鍵は警告ではなく誤りになります。すぐに上げられないときの備えとして使えます(当社の見立て)。
PyJWTでは10月にも、Ubuntuの配る版で6件の修正がありました(Canonical、PyJWTの脆弱性6件を修正 Ubuntuの認証処理を確認)。
影響する会社・しない会社
- 影響する: 社内で作ったPythonのWebアプリやAPIで、PyJWTを使い、JWKやJWKSから受け取った共有の鍵でHS系のトークンを確かめている会社です。2.13.0以前なら対象です。
- 影響する: 委託先が作ったPythonのシステムで、ログインや社内の連携にJWTを使っている会社です。PyJWTの版と使い方を委託先に確かめます。
- 影響しない: PyJWTを使っていない、またはRS256など公開鍵の署名だけを確かめている会社です。共有の鍵を文字列で渡す使い方は、2.13.0以降なら空の鍵を止めます。