openid / openid/connect-key-binding

cnf.jwk reuse across an RP's own apps can defeat OIDC Core's pairwise-identifier privacy design

Open
#30 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
0
Forks
4
PR merge metrics
No merged PRs in 30d

Description

Summary: An RP may register multiple client_ids for its own apps (Android, iOS, web) within one RP Trust Boundary. By default, OIDC Core treats each client_id as its own privacy sector, so a pairwise OP issues each app a distinct, non-correlatable sub. This spec only SHOULDs a unique key pair, and only bars reusing it "for other purposes" — not reusing it across the RP's own apps. A DPoP key reused across those apps embeds a directly-matchable plaintext value in ID Tokens that the OP deliberately kept uncorrelatable, undoing that protection through a channel the OP doesn't control.

Evidence: §9.6: "To prevent token confusion attacks, the RP Authenticating Component SHOULD bind a unique key pair to its ID Tokens, and not use it for other purposes." — a SHOULD, and scoped only to "other purposes," not to distinct client_ids/sectors. §1.2 (RP Trust Boundary definition): "An RP MAY register more than one client_id with an OP, commonly one per application... All such registrations belong to the same RP and are within the same RP Trust Boundary." OIDC Core defines a Pairwise Pseudonymous Identifier as "an identifier that identifies the Entity to a Relying Party that cannot be correlated with the Entity's PPID at another [sector]" — sectors default to per-client_id unless the RP configures a shared sector_identifier_uri.

Impact: Without key binding, nothing lets a party correlate two pairwise-distinct ID Tokens for the same End-User across the RP's own apps. With key binding, if the RP Authenticating Component reuses one key pair across apps (permitted as written), an outside party who intercepts either ID Token can trivially match cnf.jwk against the other and correlate the user across apps the OP tried to keep unlinked — a genuinely new capability that doesn't exist without key binding, since sub alone gives no cross-sector match. The OP is offering sector-unlinkability as a privacy control to the End-User, not to the RP, so a shared Consuming Component inside the RP's own trust boundary being able to correlate its users some other way (shared backend, device IDs) doesn't answer this finding — key reuse lets the RP silently void that promise through a channel the OP can neither see nor police, independent of whatever other means the RP might also have.

Suggested fix: Change §9.6 to a MUST scoped explicitly to distinct key pairs per client_id/sector (not just "other purposes"), or add privacy-considerations text flagging that key reuse across an RP's own sectors undermines pairwise-identifier privacy and stating the expected behavior.

Note to reviewers: Considered whether this is just the known DPoP access-token key-reuse tradeoff already accepted elsewhere — it isn't the same case: access tokens are typically opaque to third parties and not paired with identity claims the way an ID Token is, and RFC 9449 itself has no privacy considerations section addressing this at all. The pairwise-correlation angle is specific to ID Tokens carrying both sub and cnf together.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with §9.6, then compare its unique-key guidance with the RP Trust Boundary in §1.2 and OIDC Core's pairwise-identifier definition. Evaluate whether reuse of cnf.jwk across client_id or sector boundaries enables correlation, and review the suggested MUST or privacy-considerations wording. Done means the privacy impact and expected key-reuse behavior are resolved in the specification.

Written by the indexing model from the issue text.

Assessment

Domain
authentication, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.