> ## Content Index
> Fetch the complete content index at: https://apisyouwonthate.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# PKCE vs Proxy
- URL: https://apisyouwonthate.com/blog/pkce-vs-proxy/
- Published: 2019-05-11T00:00:00.000Z
- Updated: 2023-03-24T12:25:10.000Z
- Author: Grant Callaghan
- Tags: #Import 2023-03-24 12:19

## Background

Logging in to a web service used to mean sending a username and password and  
getting a cookie in return. This cookie is then sent with every request so that  
the server knows who is making the request. However, when it became more common  
for services to interact with each other on a user's behalf, other forms of  
authorization systems evolved. One such system is OAuth, which uses  
token-based authentication instead of cookies.

OAuth is an **Authorization** framework that allows three different parties to  
interact with a minimum level of trust. This way only one service needs to know  
your username and password. The service that doesn’t store this information  
can ask the service that does to verify who the user is and what they are allowed  
to do. In general, this provides a better, more secure, user experience.  
A user can maintain their profile and password information in a single place  
and have that referenced automatically when they connect to other services. No  
more typing in email addresses to every site and updating it in multiple places  
if it changes. This is how **Login with Facebook** or **Login with Google**  
buttons work.

Unfortunately, there are a couple of inherent security risks with this approach.  
One service is not as trustworthy as another. You might want to allow that  
budgeting app to read your account balance, but you probably don’t want it to  
empty your checking account. Additionally, the first time services  
communicate they must go over a public network where anybody can be listening.

In order to protect the credentials and limit what those credentials can do  
some initial trust needs to be bootstrapped ahead of time. This  
is done by combining two different components to ensure that the  
recipient of a temporary public credential is, in fact, the one it is intended  
for. If you have heard of two-factor authentication **(2FA)**, it's like that but  
for web services.

There are a couple of methods that use this combination of factors to provide  
some extra confidence the service getting access is the right one. We’ll take a  
look at two of those; **Authorization Code Flow** and  
**Proof of Key Code Exchange**.

## Authorization Code Flow

*Protection by Proxy*

**Authorization code** flow is the classic way to do this when a client that has a  
server component. This server component protects an OAuth **client secret** and  
proxies the token request from the client to the **Authorization Server**. In this  
flow, a user is redirected from the service hosting the protected resources to  
an **Authorization Server**. The **Authorization Server’s** job is to authenticate the  
user and approve access. After successfully authenticating, usually with a  
username and password, the user is redirected back to the service with some  
extra URL parameters including an **authorization code**.

The **authorization code** is a temporary code needed to retrieve the **access token**  
for permission to interact with the **relying service's** resources. The **relying** 
**service** then exchanges the **authorization code** combined with their **client id** and  
**client secret** for an **access token** and optionally a **refresh token**. The **relying** 
**service** then returns these to the user's client, usually a browser or mobile  
application. The client then uses this token to tell the **resource server** who  
the request is for and what permissions they have.

![Authorization Code Flow](https://storage.ghost.io/c/b4/3e/b43eb8f8-cafd-49ee-ab1f-e4fe989d2890/content/images/posts/auth-code-flow.png)

## Proof of Key Code Exchange (PKCE)

*Cryptographic Pixie Dust*

With the rise and popularity of mobile apps and Single Page Applications (SPA) a new  
flow had to evolve to accomodate public clients. These clients cannot properly  
protect a **client secret** since they run in an environment not controlled by the  
application owner. These are often either a mobile device or JavaScript in the browser. To  
compensate for the lack of confidentiality the flow extends the **authorization** 
**code** flow using cryptography to generate a **code verifier** and a **code challenge**  
for every **authorization code** exchange. During the request to get an  
**authorization code** the **relying service** includes the **code challenge**. Then when  
the **relying service** receives the **authorization code** it exchanges that in  
addition to the **code verifier**. The **authorization server** then uses the **verifier**  
to confirm the original **code challenge**.

![PKCE Flow](https://storage.ghost.io/c/b4/3e/b43eb8f8-cafd-49ee-ab1f-e4fe989d2890/content/images/posts/pkce-flow.png)

## Why not exchange the password for a token?

Exchanging the password for a token is called the **Resource Owner Credential** 
**Flow**. This flow is not recommended unless there is a HIGH level of trust between  
the **Authorization Server** and the client. When the client is JavaScript or a  
mobile app the trust just isn’t there. The previous flows allow the for  
interaction outside of the initial client for exchanging the password with the  
**Authorization Server**. For example, on a mobile device, the application might  
open a browser to begin the exchange and finish at an app-specific URL to  
complete it. This way the mobile application never has to handle the username  
and password directly.

## What does this buy us?

In both **Authorization Code** and **PKCE** flows, two factors must be exchanged for valid  
credentials. The **authorization code**, as presented as part of a redirect URL for  
consumption, along with some additional information posted in the body of the  
**access token** request. These two channels of communication mitigate a variety of  
attacks and misconfigurations where bearer tokens or authorization can be  
intercepted in flight.

However, with **PKCE** there is one more consideration to take into account and that  
is where the **Authorization Server** redirects after authentication. The client  
tells the **Authorization Server** where it wants to receive the code in the URL. If  
this is not an exact match, it means there is an opening for a malicious client  
to trick the **Authorization Server** to send the code somewhere else. That same  
client can also generate the temporary secret code. While **PKCE** moves the  
goalposts in terms of difficulty, it still relies on this redirect as an anchor  
of trust.

While having a fully qualified redirect URL is a best practice,  
**Authorization Code** flow mitigates an open redirect misconfiguration due to the  
fact that the server still holds a predetermined secret. Because the secret used  
in **PKCE** is generated at runtime, a malicious actor capitalizing on an open  
redirect can still follow to the protocol to get valid credentials. On mobile  
clients, this is an app-specific URL such as  
`app-foo://auth_code_handler#code=XXX`. For SPA’s this would be something like  
`https://app.foo.com#code=XXX`.

While **PKCE** was originally intended for mobile applications the [OAuth Best Practices Working Group](https://tools.ietf.org/html/draft-ietf-oauth-security-topics-11?ref=apisyouwonthate.com#section-2.1.1)  
has recently started to recommend it for SPA’s as well.

To add a **PKCE** flow to your application take a look at [https://appauth.io/](https://appauth.io/?ref=apisyouwonthate.com) for  
supported libraries and implementations.