# OAuth, OIDC, and SAML: transaction binding and token trust

Separate browser transaction binding, issuer trust, token purpose, and identity linking using controlled federation fixtures.

## Investigation sequence

1. Map issuers and clients
2. Capture authorized flow
3. Alter one binding
4. Verify token semantics
5. Check replay and linking
6. Remove test grants

## Used in these playbooks

[Web & API](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/web-api.html) · [OSS & self-hosted](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/oss.html) · [Mobile](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/mobile.html) · [Desktop & extensions](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/desktop.html) · [Cloud & containers](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/cloud.html) · [AI, agents & MCP](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/ai.html)

### Setup and trust record

Use two controlled accounts, two registered lab clients when available, and a test identity provider. Record authorization server, client ID/type, exact redirect URI, grant, scopes, resource/audience, browser transaction, issuer/subject, and resulting local account. Pin deployed protocol profiles and libraries. Reuse the [session lifecycle](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/identity-session.html) and [authorization matrix](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/modules/authz-matrix.html); this procedure adds federation-specific decisions.

The invariant is: **a valid credential for one transaction, client, issuer, or purpose must not silently authorize another**. A decoded token, valid cryptographic signature, and successful login are three different observations.

### Numbered procedure

1. **Establish browser binding.** Capture a normal authorization-code login and a separate account-link operation. In the replica, deliver A's response into B's pending transaction and compare the resulting local account/link with untouched controls. Track which session initiated each transaction. Missing `state` alone is not decisive when transaction-specific PKCE or another valid mechanism provides the required binding. Validate a registered redirect with exact matching, accounting for the native loopback-port exception. [RFC 9700](https://www.rfc-editor.org/rfc/rfc9700.html).
2. **Check code and PKCE handling independently.** On separate fresh authorization codes, compare the correct verifier, a wrong verifier, and a missing verifier. Then replay one already redeemed code. Where the flow supports PKCE, inspect whether removing the challenge can create a downgrade path. Keep client authentication, client ID, and redirect constant so rejection can be attributed correctly. A verifier is secret; a public challenge is not. Generate a new verifier for each real transaction. [PKCE specification](https://www.rfc-editor.org/rfc/rfc7636.html).
3. **Validate OIDC context.** With the lab issuer, produce otherwise valid fixtures with one wrong issuer, client audience, expired time, or mismatched nonce when that flow requires it. Check profile-specific `azp`, hash, and authentication-age rules rather than assuming every claim is universal. Local identity should use the issuer/subject pair; equal email claims do not establish that two identities may be merged. Compare UserInfo subject with the ID-token subject when UserInfo is used. [OpenID Connect Core](https://openid.net/specs/openid-connect-core-1_0.html).
4. **Test JWT trust and purpose.** First show rejection of one invalid signature. Then use validly signed local fixtures for another resource or purpose: an ID token at an access-token endpoint, or an email-verification token at a session endpoint, where the implementation exposes that path. In source review, inspect algorithm allowlists, issuer-selected key material, key-ID lookup, and mutually exclusive validation rules. Do not turn a token-supplied key URL into a production callback experiment. A signature-valid but unauthorized token is a semantic trust failure, not necessarily broken cryptography. [RFC 8725](https://www.rfc-editor.org/rfc/rfc8725.html).
5. **Check refresh replay under the actual design.** Record original and rotated refresh credentials separately. After one normal rotation, attempt the previous credential once from another local client and inspect both the returned token and a harmless resource read. If tokens are sender-constrained, test the relevant missing/wrong sender proof instead. Public-client refresh tokens require rotation or sender constraint; documented retry grace affects interpretation but does not erase demonstrated independent unauthorized access. [OAuth refresh-token protection](https://www.rfc-editor.org/rfc/rfc9700.html).
6. **Follow SAML from verified bytes to identity.** In a local IdP/SP pair, compare a normal response with independently changed signed content, a wrongly targeted assertion, an expired assertion, and one replay. Trace the exact signed element from which the SP consumes identity and attributes; verifying an unrelated signed element is insufficient. For SP-initiated SSO check request correlation. For supported IdP-initiated SSO, missing request correlation is expected, but replay and recipient/trust checks still matter. Keep RelayState handling separate from assertion integrity. [OWASP SAML processing](https://cheatsheetseries.owasp.org/cheatsheets/SAML_Security_Cheat_Sheet.html).

### Local command card

Prepare `expected.header` and `other-resource.header` using **valid tokens minted by your lab issuer**; each contains its complete `Authorization: Bearer …` line. The second token is intentionally valid only for a different resource under the issuer policy. Preserve the same subject and request where possible. The protected route is illustrative. These requests do not test a public provider.

```bash
mkdir -p evidence/federation
chmod 600 expected.header other-resource.header
curl -q --noproxy '*' --max-time 10 --header @expected.header \
  -D evidence/federation/expected.h -o evidence/federation/expected.json \
  http://127.0.0.1:8000/api/me
curl -q --noproxy '*' --max-time 10 --header @other-resource.header \
  -D evidence/federation/wrong-resource.h -o evidence/federation/wrong-resource.json \
  http://127.0.0.1:8000/api/me
```

A 401/403 is a useful control, but also inspect bodies and resulting identity. Successful use of the expected token establishes only the baseline. Token transport and audience selection must match the actual local deployment.

### Evidence and checklist

Capture one invalid condition, accepted identity or capability, minimal synthetic response, and the intended trust configuration. Document any test signing keys you supplied: possession of the real IdP signing key already grants authority and is not a new bypass. A rejected code, intentional multi-audience policy, or unconsumed altered claim is not takeover evidence.

- [ ] Browser binding and token validity tested separately.
- [ ] Correct, wrong, omitted, and consumed proof cases kept distinct.
- [ ] Token purpose and issuer/audience validation separated from signature validation.
- [ ] SAML consumed identity traced to the validated signed element.
- [ ] Grants, sessions, test keys, and transient credentials removed after evidence capture.


## Vulnerability reverse references

- [OAuth login or account-linking confusion](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/oauth-login-account-linking-confusion.html) — An authorization response or external identity is bound to the wrong application session or controlled account.
- [JWT signature, issuer, audience, or token-purpose validation failure](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/jwt-signature-trust-failure.html) — A service accepts token claims without the required signature or trusted issuer/key validation.
- [SAML assertion signature, audience, or response binding failure](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/saml-assertion-trust.html) — The service provider trusts an assertion whose signature or authentication context is not valid for the receiving flow.
- [Verification or account merge preserves another actor's access](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/identity-verification-merge-confusion.html) — Registration, verification, email change, or federation merging transfers trust to an identity while retaining an unintended actor's usable credentials or session.
- [Enforced SSO bypass through an alternate login path](https://bug-bounty-field-manual.kmahshooq.chatgpt.site/vulnerabilities/enforced-sso-alternate-login-bypass.html) — A protected tenant requiring federation remains accessible through a local or alternate authentication path outside the documented exceptions.
