FORSMILE
EN
セキュリティ2026/09/29

【修正版なし】Authlib CVE-2026-96760:JWSのJSON形式で署名検証が丸ごと飛ぶ — 1.8.0も未修正、deserialize()を避けて回避する

PythonのAuthlibに、署名の無いJWSを「検証済み」として返す脆弱性が公表されました(CVE-2026-96760)。鍵も署名も要りません。2026年9月29日時点で修正版は出ておらず、CVEが挙げる1.7.2より新しい1.8.0でも該当コードは変わっていません。ただし通る経路は限られており、JWTのdecodeは影響を受けません。

← ブログ一覧へ / Back to Blog

PythonのAuthlibに、署名が付いていないJWSを「検証済み」として返してしまう脆弱性が公表されました。CERT/CC が 2026年9月28日に公表し、JPCERT/CC が 9月29日に JVNVU#99151548 として転載しています。CVE番号は CVE-2026-96760 です。
攻撃者は鍵も署名も持たずに、好きな内容のペイロードを「検証済み」として通せます。CERT/CC は、身元の詐称による認証回避、権限昇格、マイクロサービス間の署名付きメッセージの偽装、スコープやロールといった認可情報の偽造を挙げています。

2026年9月29日時点で、修正版は出ていません。CERT/CC は理由も書いており、「ベンダーと連絡が取れず、この脆弱性の調整ができなかった。本稿の執筆時点で公式のパッチは提供されていない」としています。そして後で詳しく書きますが、CVEが「1.7.2以下」と書いている一方で、それより新しい 1.8.0 でも該当コードは1文字も変わっていません。
一方で、通る経路は限られています。
JWSの「JSON Serialization」を受け取る処理だけが対象で、Authlib の JWT の `decode()` は影響を受けません。まず自分がどちらなのかを切り分けてください。

⚠ CVE Score — 未評価 / NOT YET SCORED
スコア未付与CVE-2026-96760
CVEレコードは公開済みです(state: PUBLISHED、採番元はCERT/CC、ID予約は2026年9月23日、公開は9月28日)。ただしCVSSスコアはまだ付いていません。CVE.orgのレコードにはCVSSの metrics が載っておらず、NVD も metrics が空で vulnStatus は Received(受領済み・未解析)です。当サイトは推測でスコアを書かないため、数字を出していません。評価が済んでいないだけで、危険度が低いという意味ではありません。

何が起きるのか

NVD に載っている説明をそのまま書きます。
「Authlib(v1.7.2以下)には署名検証の回避の脆弱性がある。`JsonWebSignature.deserialize_json()` は JSON Serialization の JWS オブジェクトを受け取り、署名を確認せず、暗号鍵も要求せずに、ペイロードを検証済みとして返す」
CERT/CC はもう少し具体的で、「`signatures` が空の配列である JWS オブジェクトを受け入れ、ペイロードを検証成功として扱う」と書いています。

★該当するコードを読むと1行で分かる

当サイトで GitHub の該当ファイルを直接確認しました。`authlib/jose/rfc7515/jws.py` の `deserialize_json()` の終盤が次のようになっています。

python
headers = []
is_valid = True
for header_obj in obj["signatures"]:
    jws_header, valid = self._validate_json_jws(
        payload_segment, payload, header_obj, key
    )
    headers.append(jws_header)
    if not valid:
        is_valid = False

rv = JWSObject(headers, payload, "json")
if is_valid:
    return rv
raise BadSignatureError(rv)

`is_valid` の初期値が `True` で、そのあとに `signatures` をループしています。
`signatures` が空の配列なら、ループは1回も回りません。つまり `_validate_json_jws()` が一度も呼ばれず、`is_valid` は `True` のまま `return rv` に到達します。署名の確認も鍵の要求も、どこにも発生しません。

★1.8.0 でも直っていない

CVEもCERT/CCも影響範囲を「1.7.2以下」と書いていますが、これは狭すぎます。当サイトで確認した結果を書きます。
`authlib/jose/rfc7515/jws.py` を v1.7.2・v1.8.0・master の3つで取得したところ、3つともファイルが完全に同一でした(SHA-256が一致)。つまり1.8.0 はこの問題の修正版ではありません。
GitHub のリリース一覧でも、最新は 2026年8月30日の v1.8.0 で、CERT/CC の公表(9月28日)以降のリリースはありません。CERT/CC の「パッチは提供されていない」という記述と整合します。

「1.7.2以下」という表記を見て 1.8.0 なら安全だと判断しないでください。当サイトが確認できたのはコードが同一であることまでで、1.8.0 で実際に攻撃が成立するかまでを検証したわけではありません。それでも、修正されていないコードを安全側に数える理由はありません。

自分が影響を受けるかの切り分け

Authlib を入れている=全部危ない、ではありません。次の順で確認してください。

  • ✓`JsonWebSignature.deserialize_json()` を直接呼んでいるかを探す。呼んでいれば該当する
  • ✓★`JsonWebSignature.deserialize()` に、外部から来る文字列を渡していないかを探す。CERT/CC も「Authlibで JWS を読み込む両方の方法が影響を受ける」として、`deserialize_json(...)` と `deserialize('{"payload":"...","signatures":[]}', key=None)` の2つを並べて挙げています。この関数は渡された値が `dict` の場合、または `{` で始まり `}` で終わる文字列の場合に、自動で `deserialize_json()` へ振り分けます。
    つまり形式を選ぶのは攻撃者側です。compact形式のつもりでも、`{...}` を送られれば脆弱な経路に入ります
  • ✓`deserialize_compact()` だけを呼んでいるなら、この経路は通りません
  • ✓Authlib の JWT を `jwt.decode()` で使っているだけなら影響を受けません。JWT側の実装は `deserialize_compact()` を呼んでおり、`deserialize_json()` を呼んでいません

パッチが出るまでにできること

修正版が無いので、コード側で塞ぐしかありません。以下は公式が示した回避策ではなく、上で確認したコードの挙動から導いたものです。自分の環境で影響を確かめてから適用してください。

  • ✓`deserialize()` をやめて `deserialize_compact()` を明示的に呼ぶ。形式の自動判定をなくせば、攻撃者が JSON形式を選べなくなります
  • ✓JSON Serialization を受け付ける必要があるなら、検証の前に `signatures` が空でないことを自分で確かめる。空配列、またはキーそのものが無い入力を拒否します
  • ✓鍵を渡さずに呼んでいないかを確認する。`deserialize_json()` のドキュメント文字列には「鍵が与えられない場合は署名検証なしで dict を返す」と元から書かれています。これは脆弱性とは別に、意図せず使うと危険な仕様です
  • ✓GitHub のリリース一覧を監視し、修正版が出たら上げる。CERT/CC も現時点の推奨をこれにしています

★CVSSスコアはまだ付いていません

この記事にはCVSSスコアを書いていません。存在しないからです。確認した結果を書きます。
CVE.orgのレコード(採番元はCERT/CC)には、CVSSの `metrics` そのものが載っていません。NVD側は `metrics` が空のオブジェクトで、`vulnStatus` は `Received`(受領済み・未解析)です。
CVEレコード自体は公開済み(`state: PUBLISHED`。ID予約が2026年9月23日、公開が9月28日)なので、番号が存在しないという意味ではありません。
数字が無いことを「大したことない」と読み替えないでください。単に評価がまだ済んでいないだけです。

そもそも `authlib.jose` は非推奨です

影響範囲を調べているときに気づいた点も書いておきます。
`authlib/jose/__init__.py` は読み込み時に非推奨の警告を出します。メッセージは「authlib.jose module is deprecated, please use joserfc instead.」で、そのあとに「It will be compatible before version 2.0.0.」という一文が続きます。
これは「2.0.0 より前までは互換を保つ」という意味で、2.0.0 で削除すると書かれているわけではありません。(`authlib/deprecate.py` が `version` 引数からこの文を組み立てています)
今回の脆弱性はこの非推奨モジュールの中にあります。急ぎの対処とは別に、移行先が公式に示されていることは判断材料になります。

同僚に共有するならこの3行

  • ▸Authlib に署名なしのJWSを「検証済み」として返す脆弱性(CVE-2026-96760)。鍵も署名も不要で、認可情報を偽造できる
  • ▸2026年9月29日時点で修正版なし。CVEは「1.7.2以下」と書いているが、1.8.0 でも該当ファイルは同一で直っていない
  • ▸影響するのはJWSのJSON形式を受け取る経路だけ。`jwt.decode()` は対象外。`deserialize()` は攻撃者に形式を選ばせるので `deserialize_compact()` を明示する

根拠にしたページ

🚨 「しまった!」と思ったら、今すぐこちらへ

被害に遭った直後・遭ったかもしれない時のための、状況別の緊急対応ガイドです。落ち着いて、上から順に対処すれば大丈夫です。

Related articles
【対象は2機種】バッファロー WSR-300HP・WEX-G300 CVE-2026-86530:判断は版番号で、Ver.2.55/Ver.1.71 より前なら今日更新2026/09/28【緊急】F5 BIG-IP APM CVE-2026-94127:OAuth認可サーバ構成なら今日対処 — 認証不要でリモートコード実行、CISAの期限は9月25日2026/09/24【緊急】Zyxel GS1900スイッチ CVE-2026-7273:10機種のファームウェアを即更新 — 48か国996台が侵入済み、うち564台は初期パスワードのまま2026/09/23【緊急】Linuxカーネル CVE-2025-39682:kTLSを使っているなら即更新 — 9月18日のKEV追加は3件、期限は本日9月21日2026/09/21【緊急】Linuxカーネル CVE-2025-39964/CVE-2026-53266:カーネル更新後に再起動を — 悪用確認済み、期限は9月21日2026/09/18