Proof-of-Possession Access Tokens

Emil Niroshan
8 min readFeb 14, 2021

I’ve being working on developing an authentication platform for enterprise solution for last couple of years . So basically we have authentication server which has build using Identity Server 4 and various client applications such as Mobile and Web applications and Server client applications uses it to authenticate and get authorize to access the our protected resources such as the APIs.

Recently we had a discussion on some security vulnerabilities associated with those client applications we use. the most concern client type was the mobile applications specially because mobile application users may connect to untrusted networks so any token leakage will allow 3rd party attacker to use it and retrieve protected data .

All past years we were used some recommended actions mitigate such issues ,

· Use PKCE flow

· Use One Time Only Refresh token

· Keep short access token lifetime

Even though we have implemented these actions the issue is still there , means still an attacker can use the access token if it leaked , reason is the access token is a bearer token and it is self contained token which means the one who possess can use it to retrieve the data from protected resources and since is it not bound to the client who originally requested and API does not care about who is the sender

Let me explain with a scenario.

In normal case, OAuth 2 Authentication client application need to obtain the access token from authentication server (in our case Identity server 4) and then use that token to access the protected resources.

And protected resources will validate the access token to authorize the request and sent the requested data back to the client, this token validation can happen in two ways depending on the token type for example if the token is self-containing and cryptographically secured then token validation can be done within the resource server, other than that resource server need to call out for authentication server via Introspection Endpoint

Authentications and Authorization process

As the diagram shows first client application need to identity himself to the authentication server and authentication server will offer access token to the client, so client can use it to communicate with protected resource.

But in case the access token is stolen by the any other malicious party then they also can use that it accesses the protected resources, because the access token is not bound to any client, and usually resources server does not have any idea about who is using the resources from the other end.

So how we suppose to stop this or how do we stop these access tokens being used by some one who should not possess of them. That is where this OAuth2 Proof-Of-Possession concept come in to play.

PoP tokens are not new , it was there from the OAuth 1.x only issue was it is too complicated to implement because of this most of app started to use bearer tokens .

So what is this PoP tokens , PoP tokens are just like jwt access tokens but they are bound to client that requested the token initially . So if the token has leaked or stolen can not be used because the key that need to verify the client is required. These key materials was never send over the wire so that make even harder to acquire the token (network-attacks).

With the new mechanism , to have PoP tokens in TLS layer this concept started to turns in to better alternative . because it is less work to handle in the application , if you use Azure App Service with .Net Core application for instance , validation of client key material will happen way before it get hit in to your application . The specification to use PoP token came with as Mutual TLS (MTLS) spec

Mutual TLS certificate Bound Access Token

Mutual TLS certificate bound access token or we call this two-way authentication make sure that the communication or the access to associated resources is done between the parties that the supposed to.

The Mutual TLS offers two approaches to authenticate clients

· PKI Mutual-TLS Method

This is the traditional way of using x.509 certificates for authentication. And depends on validation of certificate chain and subject distinguish name (DA),So simply here the client will be successfully authenticated if the subject information are matches the expected subject configured or registered for that particular client

· Self-Signed Certificate Mutual-TLS Method

This method support authentication using self-singed certificates, here client need to register its X.509 certificate or add reference to it using jwk_URI with the authorization server. Here the client certificate chain is not validated by the server, the client will be success fully authenticated if the certificate that offers during the initial handshake matches the one of the certificates that configured on the server for the client. this is much simpler version that having full blown CA/PKI style but with similar benefits.

Bellow I have shown how the authentication and authorization process being handle within Client , Authorization Server and the API (resource server )

MTLS Certificate Bound Access token process

Step 1 : Client need to send the certificate when trying to request the token from the token server

Step 2 and Step 3 : The token server will validate it with the client settings and bind the certificate thumbprint as “x5t#S256” (base64url-encoded SHA-256 hash of the DER encoding of the X.509 certificate)

This will be added as a claim to access token (cnf)

JWT access token claims

Step 5 : Client application then use the access token communicate with API , and it is required to use the same client certificate to authenticate to the API as one used for Authorization server

Step 6 : API will verify that client certificate used for Mutual TLS and the certificate associated with the access token matches , if those are not matched then the resources access should be rejected either with 401 or 403

How ever when you try to implement this in your environment there will be some problems you might run in to , As I mention earlier I am using identity server 4 . So one of the issue I had was how to host the MTLS endpoints . My applications are running on Azure in Azure App Service and I cant simply enable MTLS to the web application as it will give some other issues , such as all the clients that uses our authentication platform does not required client certificate for example SPA (Single-Page-Applications) where MLTS not really applicable . so we have to make sure that only MTLS URLs require the certificate authentication . in azure app services we can add certification exclusion paths . Or you can change client certificate mode to Allowed , there application will request cert but will not fail the request if cert is not presented . it is up to you to decide how your authentication service should behave

Azure app service configurations

once you config your hosting layer you need to setup your ASP.NET Core application(IdentityServer app ) as well . but since we are hosting application on Azure App Service we don't need to configure certification forwarding configurations because it is already setup in the certificate forwarding middleware . only thing we have to do is call that middleware in Configure method

Enabling Certificate Forwarding Middleware

Once the certificate is loaded to the application we need to setup authentication handler

Certificate Authenticate Handler

Next you need to enable MTLS in Identity Server ,I have used path-based endpoints

Identity Server Configurations for MLTS

After successfully configured Identity Server your Discovery Document should include MTLS endpoints like below

MTLS Endpoints

I have created a test server client to test functionality of PoP token . So basically I have created a server client which uses ClientCredentials grunt type and uses X509 certificate

Server client settings

Here we need make sure that we use generate x509 certificate via a Client Authentication EKU if not certificate will be rejected

Then you can use that x509 certificate to request PoP access token from Identity Server

Now we need to make sure our API can validate certificate thumbprint , As for other services certification validation will happen on TLS layer but we need to add functionality to compare with the certificate thumbprint and access token cnf claim value

Enable to accept both certificate and bearer token
Middleware to validate cnf claim
Adding Middleware in pipeline

for further information and implementation please visit Identity Server MTLS

Summery

Mutual-TLS Client Authentication and Certificate-Bound Access Tokens or PoP tokens will increases the application security to another level mainly for the application which uses financial APIs , such as Accounting, Banking . and it is recommended practice to use MTLS in confidential clients (Financial-grade API)

However there are some security consideration we need look in to when we do implement this in our applications for example

Certificate Thumbprint Binding

Here we talk about the adding/binding certificate thumbprint in to the access token in cryptographic hash of the certificate, currently it is bind as “x5t#S256” (base64url-encoded SHA-256 hash of the DER encoding of the X.509 certificate). Goal is here to make sure it computationally infeasible to find or create another certificate that produces to the same hash output value. but if you need to change it in to better way in future it is suggested that, for additional related JWT confirmation methods, members be defined for that purpose and registered in the IANA “JWT Confirmation Methods” registry for JWT “cnf” member values.

X.509 certificate spoofing

In PKI client Authentication approach there can be situation where an attacker try to impersonate client using using a certificate with the same subject but issued by a different CA that the authorization server trusts. So here we have to make sure that our authorization server should only accept , as trust anchors, a limited number of CAs whose certificate issuance policy meets its security requirements.

--

--