Home / Knowledge hub / PKCE
Knowledge hub
PKCE
An extra check that stops a stolen OAuth code from being swapped for a token.
What it means
PKCE, short for Proof Key for Code Exchange and said "pixy", is an extension to the OAuth authorisation code flow, defined in RFC 7636. Before the sign-in, the app makes a random secret called the code verifier and sends only its hash, the code challenge, with the request.
When the app later swaps the authorisation code for tokens, it must send the original verifier. The server hashes it and compares. A thief who intercepted the code does not have the verifier, so the swap fails. Without the verifier, the code is useless to them.
Why it matters
Authorisation codes travel through the browser or a mobile app's redirect, where other software can sometimes read them. Without PKCE, whoever grabs a code can try to exchange it. Mobile apps and single-page apps cannot keep a client secret, so they have nothing else to stop that.
The current OAuth security guidance, RFC 9700, requires public clients to use PKCE and recommends it for all clients. It also helps against code injection, where an attacker plants their own code in a victim's session. Skipping it is a finding in many reviews.
How it shows up
You meet PKCE in sign-in with a social or company account, in mobile apps, and in single-page apps. Most good libraries switch it on for you. Check that your authorisation server actually requires it, because supporting it and enforcing it are different.
Common mistakes: using the plain method when S256 is available, a weak or reused verifier, a verifier kept in a place other code can read, and a server that accepts a code request without a challenge. An attacker may simply leave the challenge out, so the server must reject a missing verifier.
Questions people ask
PKCE, answered
Is PKCE only for mobile and single-page apps?
It was designed for them, but it is recommended for all clients now, including those with a client secret. It guards against a different risk from the secret.
What is the difference between S256 and plain?
S256 sends a SHA-256 hash of the verifier. plain sends the verifier itself, which gives much less protection. Use S256 unless a client cannot hash.
Does PKCE replace the state parameter?
No. The state value guards against cross-site request forgery on the redirect. PKCE can also help there, but the OAuth guidance still says to protect against it explicitly.
Does PKCE stop phishing?
No. If a user is tricked into authorising an attacker's app, PKCE does not help. It protects the exchange of the code, not the choice of who gets access.
How do we test that PKCE is enforced?
Start a sign-in, copy the code and try to exchange it without a verifier, then with a wrong one. Both should fail. If either works, the server is not enforcing it.
Related
Terms that sit next to this one
OAuth redirect URI
The address a sign-in provider sends the user back to, which must be matched exactly.
OpenID Connect
A sign-in layer on top of OAuth that tells your app who the user is.
Token
A string that stands in for an identity or a permission.
Single sign-on
One company identity for many applications, granted and removed in one place.
Authentication
Proving you are who you say you are. It answers one question only.
Can a stolen code be used?
We test sign-in flows for weak code exchange and unsafe redirects, and each finding carries the exact requests we sent. Book a pilot on one app.
Or start with a $199 pilot on one application: thirty days, success criteria agreed before day one, credited against the annual if you convert.