Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐹
🐹 Go
Not in CISA KEV
MEDIUM severity

CVE-2026-41164 nuts-node

MEDIUM

CVE-2026-41164 is a medium-severity (CVSS 4.4) CWE-345 vulnerability in github.com/nuts-foundation/nuts-node. No vendor fix is recorded yet; mitigation options are listed below.

nuts-node: JWT type confusion in v1 access token introspection allows VP replay as access token

Also known asGHSA-9hmg-827w-9rhjGO-2026-5291
Published
May 26, 2026
Updated
Aug 12, 2026
Affected
1 pkg
Patched
None yet
Exploits
None indexed
Exploitation data as of Sep 22, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-41164.

EPSS Exploitation Probability

via FIRST.org ↗
0.1%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs0th percentile — riskier than 0% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

CVE-2026-41164 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 377,636 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

1 pkg affected
🐹github.com/nuts-foundation/nuts-node

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.

Description

Summary

The v1 access token introspection endpoint (/auth/v1/introspect_access_token) accepts any JWT signed by a key present on the node, without validating the JWT type, issuer-to-key binding, or required claims. This allows a Verifiable Presentation (VP) JWT to be replayed as an access token and receive an active: true introspection response.

Background

In the v1 auth flow (Nuts RFC003), access tokens are JWTs signed by the authorizer's key with:

  • iss = authorizer organization DID
  • sub = requester organization DID
  • service = purpose of use (e.g. "eOverdracht")
  • typ header = "JWT" (default, not explicitly set)

Verifiable Presentations are also JWTs with typ: "JWT" (per W3C VC Data Model 1.1). The W3C VC Data Model 2.0 changed this to vp+jwt specifically to prevent this class of confusion attack (See Securing Verifiable Credentials using JOSE and COSE 3.1.1).

Vulnerability details

The introspection endpoint performs only standard JWT checks. It does not perform the following Nuts-specific access token checks:

  1. Validate the typ header: both ATs and VPs use "JWT"
  2. Bind iss to the signing key: it doesn't verify that the iss claim matches the DID extracted from the kid
  3. Validate required claims: service can be empty; vp claim is silently ignored by FromMap() which uses lenient JSON unmarshaling

Attack scenario

Prerequisites: Attacker (Org B) has received a VP JWT from the victim (Org A) during a normal access token request flow.

  1. Org A creates a VP JWT signed with Org A's key and sends it to Org B (normal protocol flow) to request an access token
  2. Org B presents this VP JWT to Org A's resource server as a bearer access token
  3. Resource server calls Org A's v1 introspection endpoint
  4. Introspection checks privateKeyStore.Exists(kid), which passes, because Org A's key is on Org A's node
  5. JSON unmarshaling is lenient; the vp claim is silently ignored
  6. Returns active: true with service: "", iss: "", sub: <Org A's DID>

Mitigating factors

  • service is empty: resource servers that strictly require a non-empty service field may reject the request at the application level
  • iss is empty: VP JWTs don't set iss, so resource servers checking this field would see an empty value
  • Short-lived VPs: VPs typically expire within minutes, narrowing the attack window
  • v1 is legacy: the v2 flow uses opaque access tokens and is not affected

Severity rationale

While the introspection endpoint incorrectly returns active: true for a replayed VP, we consider this not practically exploitable in the current deployment landscape. Resource servers require valid service, iss and aud values to route requests to the correct databases. A replayed VP returns empty service, empty iss, and wrong sub (Org A instead of B), making it unusable for meaningful access. The attack also requires the victim to first present a VP to the attacker through a legitimate protocol flow, and VPs are short-lived.

The severity reflects that the protection against exploitation is accidental (resource servers need service for routing, not for security) and we cannot guarantee how all resource server implementations handle the active: true response with missing fields.

The fix

Affected versions: all v5.x releases prior to v5.4.31, and all v6.x releases prior to v6.2.3. From v5.4.31 and v6.2.3 onward, the following checks have been added to IntrospectAccessToken:

  1. iss-to-kid binding: extract the DID from the kid header and verify it matches the iss claim
  2. Required claims validation: reject tokens where service is empty
  3. typ header validation: requires access tokens to be of typ: "at+jwt"

Additionally, the access token creation code has been updated to use typ: "at+jwt" per RFC 9068.

Patch

Patches are available at https://github.com/nuts-foundation/nuts-node/releases/tag/v5.4.31 and https://github.com/nuts-foundation/nuts-node/releases/tag/v6.2.3.

Workaround

If users are unable to update their nuts-node, resource servers can mitigate this risk by explicitly validating the introspection response: reject responses where service is empty, where iss is empty or does not match the expected authorizer DID, or where sub does not match the expected requester DID (Org B instead of A).

Affected Packages

1 total
EcosystemPackageVulnerable rangeFix
🐹Gogithub.com/nuts-foundation/nuts-nodeall versionsNo fix

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/nuts-foundation/nuts-node, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Remediation status

    No patched version of github.com/nuts-foundation/nuts-node has shipped for CVE-2026-41164 yet. Where your build allows, override or pin the dependency away from the vulnerable range, and apply any maintainer-recommended mitigation.

  3. Mitigate without a patch

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2026-41164 can be triaged on real exposure rather than presence alone.

Tailored to CVE-2026-41164. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

## Summary The v1 access token introspection endpoint (`/auth/v1/introspect_access_token`) accepts any JWT signed by a key present on the node, without validating the JWT type, issuer-to-key binding, or required claims. This allows a Verifiable Presentation (VP) JWT to be replayed as an access token and receive an `active: true` introspection response. ## Background In the v1 auth flow ([Nuts RFC003](https://nuts-foundation.gitbook.io/v1/rfc/rfc003-oauth2-authorization)), access tokens are JWTs signed by the authorizer's key with: - `iss` = authorizer organization DID - `sub` = requester or
O3 Security · Impact-Aware SCA

Is CVE-2026-41164 in your dependencies?

O3 Security finds CVE-2026-41164 across Go dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.

CVE-2026-41164: nuts-node (Medium 4.4) | O3 Security