A client secret only helps when the secret actually stays with the legitimate client. In interception and injection scenarios, the attacker either steals the code before redemption or tricks the client into redeeming the wrong code. PKCE adds a separate proof of possession, so the exchange fails unless the verifier matches the original challenge.
Why code interception makes the token exchange fragile
Code interception is a problem because the authorization code is a short-lived bearer artifact that only has value if the right party redeems it. If an attacker can steal the code before the legitimate client exchanges it, the client secret does not help, because the attacker can still win the race or replay the code from a different path. The danger is the front half of the flow, not just the client authentication step.
PKCE changes that trust model by binding the code to a proof that the original client created the request. Without that extra proof, a stolen code can be redeemed by whoever sees it first, which is why interception remains a token risk even in flows that already use a client secret.
Where the client secret helps, and where it does not
A client secret authenticates the client at the token endpoint, but it does not prove that the authorization code being presented is the one issued for that client session. In practice, interception attacks exploit the gap between code issuance and code redemption. If the secret is intact but the code has been intercepted, the attacker may not need to know the secret at all if they can cause the legitimate client to exchange the wrong code or if they can redeem the stolen code using their own valid client path.
This distinction matters in OAuth deployments because transport protection and client authentication solve different problems. A confidential client secret reduces some forms of client impersonation, but it does not by itself prevent code substitution, code replay, or interception on the user-agent or redirect path. That is why modern guidance treats proof of possession as a separate control, not as a replacement for client authentication.
When people say “the client secret is enough,” they usually mean the secret is enough to identify the client at redemption time. It is not enough to prove that the authorization response was not intercepted or substituted before redemption. That is the security gap PKCE was designed to close.
Why PKCE is the control that closes the gap
PKCE adds a verifier and challenge pair so the token request must present the same proof that was used when the code was issued. The result is simple: a stolen authorization code is no longer sufficient on its own. Even if the attacker can see the code, the token exchange fails unless the verifier matches the original challenge.
That makes PKCE especially important for public clients, browser-based apps, mobile apps, and any flow where the redirect channel or authorization response may be exposed to interception or injection. It also improves security for confidential clients when there is any realistic risk that the front-channel response could be tampered with before the client redeems it.
For a deeper treatment of the control model, the OWASP Non-Human Identity Top 10 covers the broader identity and secret risks that arise when credentials or tokens can be intercepted, replayed, or overused. In OAuth-specific deployments, the standards that matter most are the ones that bind the token to the client or sender, not the ones that only authenticate the client at the end of the flow.
Risk and Threat Considerations
Code interception creates a race condition and a substitution problem. The attacker can steal the authorization code from the redirect path, from a compromised browser context, or by injecting a malicious redirect target, then redeem it before the legitimate client does. If the design assumes the client secret alone is sufficient, the system can still issue tokens to the wrong party.
Failure mechanism: The authorization code is treated as reusable or unbound to the original request, so interception, replay, or injection lets an attacker complete the exchange without the legitimate client’s proof.
Impact: Token issuance can be diverted to the attacker, leading to account compromise, session hijack, or unauthorized API access even when the client is otherwise authenticated.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP API Security Top 10 and OWASP Non-Human Identity Top 10 address the attack and risk surface, while NIST SP 800-53 Rev 5 and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP API Security Top 10 | API2 — Broken Authentication | Authorization code interception weakens OAuth client authentication and token exchange integrity. |
| Recommendation — Require PKCE and sender-constrained exchanges to prevent stolen codes from being redeemed. | ||
| NIST SP 800-53 Rev 5 | IA-5 — Authenticator Management | Client secrets and PKCE verifiers are authenticators that need lifecycle and protection controls. |
| IA-9 — Service Identification and Authentication | OAuth clients and token endpoints use machine-to-machine authentication for redemption. | |
| Recommendation — Protect and rotate authenticators, and bind redemption to the intended client. Use stronger client authentication and bind tokens to the presenting client. | ||
| OWASP Non-Human Identity Top 10 | NHI-04 — Insecure Authentication | Stolen authorization codes can be redeemed when proof of possession is missing. |
| NHI-07 — Long-Lived Secrets | Client secrets reduce but do not eliminate abuse if code flow security is weak. | |
| Recommendation — Add proof-of-possession checks so intercepted codes cannot be exchanged alone. Prefer short-lived, bound credentials and avoid relying on static secrets alone. | ||
| NIST CSF 2.0 | PR.AA-05 — Identity Management, Authentication and Access Control | The flow depends on authenticating the client and controlling token issuance. |
| Recommendation — Enforce bound authentication so only the intended client can complete redemption. | ||
Practitioner Guidance
What to verify: Confirm that the code exchange uses PKCE for every flow that can be intercepted in the front channel, and do not treat client authentication as a substitute for code binding. If the application still relies on a plain authorization code exchange, assume interception risk remains.
Decision rule: If the authorization response can pass through a browser, mobile redirect, embedded web view, or any untrusted intermediary, require proof-of-possession binding in addition to the client secret. If the flow is already sender-constrained or otherwise protected against code replay, document that control rather than assuming the secret covers it.
What practitioners underestimate: The secret protects the client identity at redemption time, but the attacker often wins earlier, by capturing or swapping the code before that check ever matters. The right question is not “does the client have a secret?”, it is “can the code be redeemed by anyone other than the party that started the flow?”
Practitioner takeaway: Treat the client secret as client authentication, not as proof that the authorization response is intact; interception risk persists until the code is bound to the original request.
Related resources from NHI Mgmt Group
- Why do APIs create identity risk even when the application code is secure?
- Why do AI code assistants create new secret exposure risk for IAM teams?
- Why do VS Code extension attacks create more risk than simple token theft?
- Why do remote desktop platforms create identity governance risk even without secret exposure?