Skip to content

fix(did): validate OIDC discovery jwks_uri targets during did:jwks resolution #191

Description

@Kewe63

Summary

did:jwks resolution currently validates/builds the initial DID-derived URLs, but the OIDC discovery fallback can return an arbitrary jwks_uri. That jwks_uri is then fetched without applying an equivalent URL policy.

This means a resolver can be made to fetch a URL that was not derived from the original did:jwks identifier and may not satisfy the same scheme/host expectations as the first-hop request.

Affected Code

  • packages/did/src/did-resolvers/get-did-resolver.ts
  • jwks-did-resolver / did-jwks resolution path

Relevant Dependency Behavior

did-jwks@1.1.0 performs this flow:

  1. fetch https://<did-host>/.well-known/jwks.json
  2. if unavailable, fetch https://<did-host>/.well-known/openid-configuration
  3. if the discovery document contains jwks_uri, fetch that URL directly

The OpenID configuration schema validates jwks_uri as a URL, but does not appear to restrict scheme, host, localhost/private-network ranges, or same-origin/cross-origin policy before fetching it.

Why This Matters

ACK's DID resolver is used underneath verification paths such as JWT verification, VC verification, ACK-ID controller verification, and ACK-Pay receipt verification. These flows may need to resolve a DID before a signature can be verified.

If an application resolves attacker-controlled did:jwks identifiers, the OIDC discovery fallback can cause server-side fetches to URLs chosen by the DID host through jwks_uri.

Minimal Reproduction

Using ACK's public resolver API with a mocked fetch:

  1. The direct JWKS endpoint returns 404.
  2. The OpenID configuration endpoint returns a jwks_uri pointing somewhere else.
  3. The resolver fetches the jwks_uri target.

Observed fetch sequence:

[
  "https://attacker.example/.well-known/jwks.json",
  "https://attacker.example/.well-known/openid-configuration",
  "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
]

Expected Behavior

did:jwks resolution should apply a URL policy to OIDC discovery jwks_uri targets before fetching them.

Possible safe defaults:

  • allow only https:// by default
  • reject localhost / loopback addresses
  • reject 0.0.0.0
  • reject RFC1918/private ranges
  • reject link-local ranges such as 169.254.0.0/16
  • reject IPv6 loopback/link-local/unique-local ranges
  • optionally require same-origin jwks_uri, or provide an explicit allowlist/callback for legitimate cross-origin JWKS providers

Relation to Existing Issues/PRs

I checked the existing issue/PR history and this does not appear to be the same as the did:web redirect issue.

Related but different:

This issue is not about following HTTP redirects. It is about the OIDC discovery document explicitly returning a jwks_uri that points to another URL. A redirect policy alone does not validate that jwks_uri target.

Suggested Fix

Wrap the fetch passed into jwks-did-resolver / did-jwks with URL validation that applies to every fetch target, including OIDC-discovered jwks_uri values.

Alternatively, expose a did:jwks-specific option such as:

  • allowedJwksUriHosts
  • allowJwksUri(url, did)
  • allowPrivateJwksUriTargets: false

and default to a conservative policy.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions