Discussion:
[OAUTH-WG] TAuth
Dick Hardt
2016-05-10 23:24:17 UTC
Permalink
Does anyone think there are useful lessons here?

Does adding TOKBIND resolve the issues?

https://blog.teller.io/2016/04/26/tauth.html

*Teller* <https://blog.teller.io/>

Join waiting list <http://teller.io/#waitlist>

Introducing TAuth: Why OAuth 2.0 is bad for banking APIs and how we're
fixing it

This week we released our authorisation flow making it possible for you to
go from building apps that talk to your bank account, to building apps that
can talk to any bank account. This is huge. Check out this SMS bot (how on
trend) I hacked up yesterday morning. (and don't forget to join the beta
wait list <https://teller.io/>).


Getting to this point took longer than we expected. This is because there
wasn't a good story for delegating authorisation for sensitive APIs. The
most popular choice, OAuth 2.0 <http://oauth.net/2> - which has been chosen
by the Open Banking Working Group <http://theodi.org/open-banking-standard>,
BBVA
<https://www.bbvaapimarket.com/web/api_market/bbva/bbva-connect/documentation#3-legged-flow>,
RBS <https://bluebank.portal.azure-api.net/getting-started>, and Mondo
<https://getmondo.co.uk/docs/#authentication> - is also amongst the worst
from a security perspective.

Teller provides an API for your bank account. The EU is forcing all
European banks to expose account APIs with PSD II
<http://ec.europa.eu/finance/payments/framework/index_en.htm> by end of
2017. These banks are disconcertingly converging around OAuth 2.0* without
fully considering the impact on their customers, and something needs to be
done before it's too late.

* One notable exception is the Open Bank Project
<http://www.openbankproject.com/>. It is sticking with OAuth 1.0a
<http://oauth.net/core/1.0a/> precisely because OAuth 1.0a doesn't share
the same security issues as OAuth 2.0.

Man-in-the-middle

One of the biggest problems with OAuth 2.0 is that it delegates all
security concerns to TLS but only the client authenticates the server (via
it's SSL certificate), the server does not authenticate the client. This
means the server has no way of knowing who is actually sending the request.
Is it a bona fide user, or is an attacker tampering with the request? When
an attacker is able to insinuate themselves between a legitimate user and
the server, it's called a man-in-the-middle (MITM) attack. It looks like
this:

- client attempts to connect to service
- attacker successfully reroutes traffic to a host it controls
- malicious host accepts connection from client
- malicious host connects to service
- service accepts connection from malicious host
- client communicates with service proxied through malicious host, which
can see and tamper with any data sent or received

You're probably thinking "hang on, isn't this the point of SSL?" Yes it is,
but there are a number of ways to present a bogus certificate and a client
accept it. The most realistic threat is the client developer not properly
verifying the server certificate, i.e. was it ultimately signed by a
trusted certificate authority?

*Follow* <https://twitter.com/tpope>

<https://twitter.com/tpope>

*Tim Pope* ‎@tpope <https://twitter.com/tpope>

Pull requests to disable SSL certificate verification: more common than you
would think.

2:24 PM - 11 Feb 2013 <https://twitter.com/tpope/status/301094352434892800>

- 5 5 Retweets
<https://twitter.com/intent/retweet?tweet_id=301094352434892800>5 5 likes
<https://twitter.com/intent/like?tweet_id=301094352434892800>

Unfortunately a large <http://stackoverflow.com/a/7332983/223213> number
<http://stackoverflow.com/a/16298999/223213> of developers
<http://stackoverflow.com/a/36154521/223213> think that disabling SSL peer
verification is the correct fix to a SSL path validation error. There are
many more that will offer the same advice with the caveat that it
introduces a security issue <http://stackoverflow.com/a/12293898/223213>
that < 100% of readers will consider. As an API provider with a duty of
care to our users we can't simply hope developers on our platform don't do
this.

Bearer tokens

Once a user authorises a client application to access its account, the
application obtains a bearer token from the authorisation server. As the
name suggests if you have possession of the bearer token then you are
essentially the user. There is no cryptographic proof that the requesting
client is the intended developer and not an attacker. If an attacker is
able to successfully MITM a client it could have catastrophic implications
for the user, e.g. an empty bank account, loans opened in their name, etc.
OAuth 2.0 is simply a security car crash from a bank's perspective. They
have no way to prove that an API transaction is bona fide, exposing them to
unlimited liability.

For more information on OAuth 2.0 shortcomings see OAuth Bearer Tokens are
a Terrible Idea
<https://hueniverse.com/2010/09/29/oauth-bearer-tokens-are-a-terrible-idea/>
and OAuth 2.0 and the Road to Hell
<https://hueniverse.com/2012/07/26/oauth-2-0-and-the-road-to-hell/> by Eran
Hammer <https://twitter.com/eranhammer> the original primary author of
OAuth 2.0 who formally removed his name from the standard, calling it "the
biggest professional disappointment of [his] career."

Finding something better

Sitting down to design the solution to this problem I had two high-level
goals:

- be the most secure solution for the user
- not unnecessarily impede developer experience. Developers are users
too and their needs deserve equal consideration.
- cryptographic proof of client identity
- to stop MITM attacks
- to unimpeachably attribute a request to a given developer. In
cryptography this is known as non-repudiation
<https://en.wikipedia.org/wiki/Non-repudiation>.

(N.B. Non-repudiation is a de facto requirement of PSD II. If a bank can't
prove an account owner authorised a transaction, they're liable for any
losses incurred by the user.)

There are solutions to the bearer token problem like JWT tokens (RFC7523
<https://tools.ietf.org/html/rfc7523>) but in most cases these rely on a
shared secret which is used to computed a HMAC-based signature. Shared
secrets mean no non-repudiation. Public key cryptography can be used with
JWT tokens but they don't solve the problem of how the client will generate
key pairs, demonstrate proof of possession of the private key, and enrol
the public key with the API. Most importantly using JWT tokens make it
basically impossible for you to experiment with an API using cURL. A major
impediment to developer experience.

In an ideal world we'd have cryptographic proof of the client's identity
without it having to leak through the application level (and stop us
cURLing the API!). As I thought about it it became the clear the answer was
hiding in plain sight: *SSL client certificates.*

Client SSL Authentication

A SSL handshake involving client certificates contains an extra message at
the end of the handshake, the *CertificateVerify*
<https://www.ietf.org/rfc/rfc2246.txt> message.

Client Server


ClientHello -------->

ServerHello

Certificate*

ServerKeyExchange*

CertificateRequest*

<-------- ServerHelloDone

Certificate*

ClientKeyExchange

CertificateVerify*

[ChangeCipherSpec]

Finished -------->

[ChangeCipherSpec]

<-------- Finished

Application Data <-------> Application Data


Fig. 1 - Message flow for a full handshake

The client collects all the handshake messages and signs them with it's
private key and sends the result to the server. The server then verifies
the signature using the public key of the client certificate. If the
signature can be verified with the public key, the server knows the client
is in possession of the private key, and is therefore a bona fide user.

Let's look at this in the context of our original attack:

- client attempts to connect to service
- attacker successfully reroutes traffic to a host it controls
- malicious host accepts connection from client accepting the client's
certificate
- malicious host connects to service
- the malicious host will fail to SSL handshake because the host doesn’t
have the private key for the client’s certificate. The attacker therefore
cannot compute the correct *CertificateVerify* handshake message. The
*CertificateVerify* message from the first handshake cannot be used
because the handshake sequences diverge (different server certificates
presented by the host).

Introducing TAuth

TAuth is Client SSL Authentication + User Tokens + Great Tooling.

Client SSL authentication is often overlooked because of the poor UX of
using client certificates in the browser and that generating certificates
is a painful multistep process involving arcane OpenSSL CLI incantations.
However as we're talking about API clients the browser UX point is
irrelevant. As far as certificate generation goes, we can write better
tools. These days it's possible to generate a key pair, a PKCS#10
certificate request, and sign it all in the browser. Thanks to WebCrypto
<http://www.w3.org/TR/WebCryptoAPI/> the whole process is reduced to one
click.

This is how Teller does it:

A private key and a SSL certificate signed by Teller generated in one click.

And this is what a request looks like with client certificates:

Let's recap what we've achieved here:

- Cryptographic proof of the client identity
- The cURLability of the API is preserved
- The client developer has generated a private key known only to them
and no one else, meaning the bank can actually say "you did that
transaction" (non-repudiation)

Token security

Notice in the above example. The Teller API accepts connections from
clients without a client certificate. We do this because we provide
developers with read-only personal access tokens for their own accounts if
they want to quickly hack something up and not bother with provisioning
certs. Now notice how the API does not accept the token presented, but
accepts it when used with the client SSL certificate. TAuth bearer tokens
are bound on the server side to a private key through an application. This
means they are useless without the private key (which only the developer
ever has) and therefore not sensitive. As matter of fact, here is one for
my bank account:


You'll need the private key it's bound to for it to be of any use, and that
has never left my laptop.

TAuth tokens do not expire (but can be revoked). OAuth 2.0 introduced the
concept of time-limited tokens. Large internet companies found it useful
for scaling purposes to issue self-encoded, encrypted tokens. The drawbacks
are developers have to pay the complexity cost of refreshing tokens and
most importantly tokens cannot be revoked, they're good until they expire.
For bank account APIs this is an undesirable property, a token should be
void as soon as the account owner wishes. TAuth checks the token revocation
status at each request.

Given that we have no need for self-encoded tokens and that tokens are
useless to anyone without the private key, we can consider them public and
directly return them in the callback further simplifying things for the
developer compared to OAuth without compromising the user's security.

Bonus: DDOS mitigation

TAuth can help mitigate layer 7 based DDOS attacks
<https://en.wikipedia.org/wiki/Application_layer_DDoS_attack> too. If the
client does not present a valid client certificate the server can just
choose to bounce the connection.

Conclusion

OAuth 2.0 is simply not fit for use with sensitive APIs and all the pieces
needed to build something that is exist today. Aside from unbound bearer
tokens, OAuth is too open-ended and complicated to get right for most
developers. It's so bad it even has it's own threat model as a separate RFC
<https://tools.ietf.org/html/rfc6819> to offer mitigations for the endless
problems that can happen.

*TAuth stands for Trusted Authentication*, and it provides the best
security for users while maintaining the highest possible quality developer
experience. Less can go wrong when everything is simpler. *If your bank has
OAuth 2.0 in production you must ask yourself, do they really know what
they're doing?*

TAuth is available in production today for our existing beta users and
we've already begun the work to make it an open standard we hope the
industry adopts. If you're at a bank and want to offer your customers the
security they deserve email me - *sg at teller.io <http://teller.io>*

Sign up for the beta waiting list at Teller.io <http://teller.io/>.
Brock Allen
2016-05-10 23:44:41 UTC
Permalink
Doesn’t the recent PoP work address many of these concerns?

Also, as for developers disabling SSL — does anyone still do this and think it’s safe? Or are people just being lazy? Or are there certain contexts that I’m unaware of where this is valid?

-Brock


From: OAuth <oauth-***@ietf.org> on behalf of Dick Hardt <***@gmail.com>
Date: Tuesday, May 10, 2016 at 7:24 PM
To: Oauth Wrap Wg <***@ietf.org>
Subject: [OAUTH-WG] TAuth

Does anyone think there are useful lessons here?

Does adding TOKBIND resolve the issues?

https://blog.teller.io/2016/04/26/tauth.html

Teller

Join waiting list

Introducing TAuth: Why OAuth 2.0 is bad for banking APIs and how we're fixing it

This week we released our authorisation flow making it possible for you to go from building apps that talk to your bank account, to building apps that can talk to any bank account. This is huge. Check out this SMS bot (how on trend) I hacked up yesterday morning. (and don't forget to join the beta wait list).



Getting to this point took longer than we expected. This is because there wasn't a good story for delegating authorisation for sensitive APIs. The most popular choice, OAuth 2.0 - which has been chosen by the Open Banking Working Group, BBVA, RBS, and Mondo - is also amongst the worst from a security perspective.

Teller provides an API for your bank account. The EU is forcing all European banks to expose account APIs with PSD II by end of 2017. These banks are disconcertingly converging around OAuth 2.0* without fully considering the impact on their customers, and something needs to be done before it's too late.

* One notable exception is the Open Bank Project. It is sticking with OAuth 1.0a precisely because OAuth 1.0a doesn't share the same security issues as OAuth 2.0.

Man-in-the-middle

One of the biggest problems with OAuth 2.0 is that it delegates all security concerns to TLS but only the client authenticates the server (via it's SSL certificate), the server does not authenticate the client. This means the server has no way of knowing who is actually sending the request. Is it a bona fide user, or is an attacker tampering with the request? When an attacker is able to insinuate themselves between a legitimate user and the server, it's called a man-in-the-middle (MITM) attack. It looks like this:
client attempts to connect to service
attacker successfully reroutes traffic to a host it controls
malicious host accepts connection from client
malicious host connects to service
service accepts connection from malicious host
client communicates with service proxied through malicious host, which can see and tamper with any data sent or received
You're probably thinking "hang on, isn't this the point of SSL?" Yes it is, but there are a number of ways to present a bogus certificate and a client accept it. The most realistic threat is the client developer not properly verifying the server certificate, i.e. was it ultimately signed by a trusted certificate authority?

Follow



Tim Pope ‎@tpope

Pull requests to disable SSL certificate verification: more common than you would think.

2:24 PM - 11 Feb 2013
5 5 Retweets
5 5 likes
Unfortunately a large number of developers think that disabling SSL peer verification is the correct fix to a SSL path validation error. There are many more that will offer the same advice with the caveat that it introduces a security issue that < 100% of readers will consider. As an API provider with a duty of care to our users we can't simply hope developers on our platform don't do this.

Bearer tokens

Once a user authorises a client application to access its account, the application obtains a bearer token from the authorisation server. As the name suggests if you have possession of the bearer token then you are essentially the user. There is no cryptographic proof that the requesting client is the intended developer and not an attacker. If an attacker is able to successfully MITM a client it could have catastrophic implications for the user, e.g. an empty bank account, loans opened in their name, etc. OAuth 2.0 is simply a security car crash from a bank's perspective. They have no way to prove that an API transaction is bona fide, exposing them to unlimited liability.

For more information on OAuth 2.0 shortcomings see OAuth Bearer Tokens are a Terrible Idea and OAuth 2.0 and the Road to Hell by Eran Hammer the original primary author of OAuth 2.0 who formally removed his name from the standard, calling it "the biggest professional disappointment of [his] career."

Finding something better

Sitting down to design the solution to this problem I had two high-level goals:
be the most secure solution for the user
not unnecessarily impede developer experience. Developers are users too and their needs deserve equal consideration.
cryptographic proof of client identity
to stop MITM attacks
to unimpeachably attribute a request to a given developer. In cryptography this is known as non-repudiation.
(N.B. Non-repudiation is a de facto requirement of PSD II. If a bank can't prove an account owner authorised a transaction, they're liable for any losses incurred by the user.)

There are solutions to the bearer token problem like JWT tokens (RFC7523) but in most cases these rely on a shared secret which is used to computed a HMAC-based signature. Shared secrets mean no non-repudiation. Public key cryptography can be used with JWT tokens but they don't solve the problem of how the client will generate key pairs, demonstrate proof of possession of the private key, and enrol the public key with the API. Most importantly using JWT tokens make it basically impossible for you to experiment with an API using cURL. A major impediment to developer experience.

In an ideal world we'd have cryptographic proof of the client's identity without it having to leak through the application level (and stop us cURLing the API!). As I thought about it it became the clear the answer was hiding in plain sight: SSL client certificates.

Client SSL Authentication

A SSL handshake involving client certificates contains an extra message at the end of the handshake, the CertificateVerify message.

Client Server



ClientHello -------->

ServerHello

Certificate*

ServerKeyExchange*

CertificateRequest*

<-------- ServerHelloDone

Certificate*

ClientKeyExchange

CertificateVerify*

[ChangeCipherSpec]

Finished -------->

[ChangeCipherSpec]

<-------- Finished

Application Data <-------> Application Data



Fig. 1 - Message flow for a full handshake

The client collects all the handshake messages and signs them with it's private key and sends the result to the server. The server then verifies the signature using the public key of the client certificate. If the signature can be verified with the public key, the server knows the client is in possession of the private key, and is therefore a bona fide user.

Let's look at this in the context of our original attack:
client attempts to connect to service
attacker successfully reroutes traffic to a host it controls
malicious host accepts connection from client accepting the client's certificate
malicious host connects to service
the malicious host will fail to SSL handshake because the host doesn’t have the private key for the client’s certificate. The attacker therefore cannot compute the correct CertificateVerify handshake message. The CertificateVerify message from the first handshake cannot be used because the handshake sequences diverge (different server certificates presented by the host).
Introducing TAuth

TAuth is Client SSL Authentication + User Tokens + Great Tooling.

Client SSL authentication is often overlooked because of the poor UX of using client certificates in the browser and that generating certificates is a painful multistep process involving arcane OpenSSL CLI incantations. However as we're talking about API clients the browser UX point is irrelevant. As far as certificate generation goes, we can write better tools. These days it's possible to generate a key pair, a PKCS#10 certificate request, and sign it all in the browser. Thanks to WebCrypto the whole process is reduced to one click.

This is how Teller does it:

A private key and a SSL certificate signed by Teller generated in one click.

And this is what a request looks like with client certificates:

Let's recap what we've achieved here:
Cryptographic proof of the client identity
The cURLability of the API is preserved
The client developer has generated a private key known only to them and no one else, meaning the bank can actually say "you did that transaction" (non-repudiation)
Token security

Notice in the above example. The Teller API accepts connections from clients without a client certificate. We do this because we provide developers with read-only personal access tokens for their own accounts if they want to quickly hack something up and not bother with provisioning certs. Now notice how the API does not accept the token presented, but accepts it when used with the client SSL certificate. TAuth bearer tokens are bound on the server side to a private key through an application. This means they are useless without the private key (which only the developer ever has) and therefore not sensitive. As matter of fact, here is one for my bank account:



You'll need the private key it's bound to for it to be of any use, and that has never left my laptop.

TAuth tokens do not expire (but can be revoked). OAuth 2.0 introduced the concept of time-limited tokens. Large internet companies found it useful for scaling purposes to issue self-encoded, encrypted tokens. The drawbacks are developers have to pay the complexity cost of refreshing tokens and most importantly tokens cannot be revoked, they're good until they expire. For bank account APIs this is an undesirable property, a token should be void as soon as the account owner wishes. TAuth checks the token revocation status at each request.

Given that we have no need for self-encoded tokens and that tokens are useless to anyone without the private key, we can consider them public and directly return them in the callback further simplifying things for the developer compared to OAuth without compromising the user's security.

Bonus: DDOS mitigation

TAuth can help mitigate layer 7 based DDOS attacks too. If the client does not present a valid client certificate the server can just choose to bounce the connection.

Conclusion

OAuth 2.0 is simply not fit for use with sensitive APIs and all the pieces needed to build something that is exist today. Aside from unbound bearer tokens, OAuth is too open-ended and complicated to get right for most developers. It's so bad it even has it's own threat model as a separate RFC to offer mitigations for the endless problems that can happen.

TAuth stands for Trusted Authentication, and it provides the best security for users while maintaining the highest possible quality developer experience. Less can go wrong when everything is simpler. If your bank has OAuth 2.0 in production you must ask yourself, do they really know what they're doing?

TAuth is available in production today for our existing beta users and we've already begun the work to make it an open standard we hope the industry adopts. If you're at a bank and want to offer your customers the security they deserve email me - sg at teller.io

Sign up for the beta waiting list at Teller.io.
_______________________________________________ OAuth mailing list ***@ietf.org https://www.ietf.org/mailman/listinfo/oauth
Justin Richer
2016-05-11 00:05:37 UTC
Permalink
I posted about this the other day. What I don't understand is that he's saying people disable TLS checks so he's going to solve it with mutual TLS? 
I need to email this guy and learn more about what he's doing. 
--Justin
 Sent from my phone
-------- Original message --------From: Brock Allen <***@gmail.com> Date: 5/10/16 6:44 PM (GMT-06:00) To: Dick Hardt <***@gmail.com>, Oauth Wrap Wg <***@ietf.org> Subject: Re: [OAUTH-WG] TAuth
Doesn’t the recent PoP work address many of these concerns?
Also, as for developers disabling SSL — does anyone still do this and think it’s safe? Or are people just being lazy? Or are there certain contexts that I’m unaware of where this is valid?
-Brock

From: OAuth <oauth-***@ietf.org> on behalf of Dick Hardt <***@gmail.com>
Date: Tuesday, May 10, 2016 at 7:24 PM
To: Oauth Wrap Wg <***@ietf.org>
Subject: [OAUTH-WG] TAuth

Does anyone think there are useful lessons here?
Does adding TOKBIND resolve the issues?

https://blog.teller.io/2016/04/26/tauth.html

TellerJoin waiting listIntroducing TAuth: Why OAuth 2.0 is bad for banking APIs and how we're fixing itThis week we released our authorisation flow making it possible for you to go from building apps that talk to your bank account, to building apps that can talk to any bank account. This is huge. Check out this SMS bot (how on trend) I hacked up yesterday morning. (and don't forget to join the beta wait list).
Getting to this point took longer than we expected. This is because there wasn't a good story for delegating authorisation for sensitive APIs. The most popular choice, OAuth 2.0 - which has been chosen by the Open Banking Working Group, BBVA, RBS, and Mondo - is also amongst the worst from a security perspective.Teller provides an API for your bank account. The EU is forcing all European banks to expose account APIs with PSD II by end of 2017. These banks are disconcertingly converging around OAuth 2.0* without fully considering the impact on their customers, and something needs to be done before it's too late.* One notable exception is the Open Bank Project. It is sticking with OAuth 1.0a precisely because OAuth 1.0a doesn't share the same security issues as OAuth 2.0.Man-in-the-middleOne of the biggest problems with OAuth 2.0 is that it delegates all security concerns to TLS but only the client authenticates the server (via it's SSL certificate), the server does not authenticate the client. This means the server has no way of knowing who is actually sending the request. Is it a bona fide user, or is an attacker tampering with the request? When an attacker is able to insinuate themselves between a legitimate user and the server, it's called a man-in-the-middle (MITM) attack. It looks like this:client attempts to connect to serviceattacker successfully reroutes traffic to a host it controlsmalicious host accepts connection from clientmalicious host connects to serviceservice accepts connection from malicious hostclient communicates with service proxied through malicious host, which can see and tamper with any data sent or receivedYou're probably thinking "hang on, isn't this the point of SSL?" Yes it is, but there are a number of ways to present a bogus certificate and a client accept it. The most realistic threat is the client developer not properly verifying the server certificate, i.e. was it ultimately signed by a trusted certificate authority?Follow
Tim Pope ‎@tpopePull requests to disable SSL certificate verification: more common than you would think.2:24 PM - 11 Feb 20135 5 Retweets
5 5 likesUnfortunately a large number of developers think that disabling SSL peer verification is the correct fix to a SSL path validation error. There are many more that will offer the same advice with the caveat that it introduces a security issue that < 100% of readers will consider. As an API provider with a duty of care to our users we can't simply hope developers on our platform don't do this.Bearer tokensOnce a user authorises a client application to access its account, the application obtains a bearer token from the authorisation server. As the name suggests if you have possession of the bearer token then you are essentially the user. There is no cryptographic proof that the requesting client is the intended developer and not an attacker. If an attacker is able to successfully MITM a client it could have catastrophic implications for the user, e.g. an empty bank account, loans opened in their name, etc. OAuth 2.0 is simply a security car crash from a bank's perspective. They have no way to prove that an API transaction is bona fide, exposing them to unlimited liability.For more information on OAuth 2.0 shortcomings see OAuth Bearer Tokens are a Terrible Idea and OAuth 2.0 and the Road to Hell by Eran Hammer the original primary author of OAuth 2.0 who formally removed his name from the standard, calling it "the biggest professional disappointment of [his] career."Finding something betterSitting down to design the solution to this problem I had two high-level goals:be the most secure solution for the usernot unnecessarily impede developer experience. Developers are users too and their needs deserve equal consideration.From a security perspective I wanted:cryptographic proof of client identityto stop MITM attacksto unimpeachably attribute a request to a given developer. In cryptography this is known as non-repudiation.(N.B. Non-repudiation is a de facto requirement of PSD II. If a bank can't prove an account owner authorised a transaction, they're liable for any losses incurred by the user.)There are solutions to the bearer token problem like JWT tokens (RFC7523) but in most cases these rely on a shared secret which is used to computed a HMAC-based signature. Shared secrets mean no non-repudiation. Public key cryptography can be used with JWT tokens but they don't solve the problem of how the client will generate key pairs, demonstrate proof of possession of the private key, and enrol the public key with the API. Most importantly using JWT tokens make it basically impossible for you to experiment with an API using cURL. A major impediment to developer experience.In an ideal world we'd have cryptographic proof of the client's identity without it having to leak through the application level (and stop us cURLing the API!). As I thought about it it became the clear the answer was hiding in plain sight: SSL client certificates.Client SSL AuthenticationA SSL handshake involving client certificates contains an extra message at the end of the handshake, the CertificateVerify message.  Client                            Server
  ClientHello        -------->                                    ServerHello                                    Certificate*                                    ServerKeyExchange*                                    CertificateRequest*                     <--------      ServerHelloDone  Certificate*  ClientKeyExchange  CertificateVerify*  [ChangeCipherSpec]  Finished           -------->                                 [ChangeCipherSpec]                     <--------             Finished  Application Data   <------->     Application Data
         Fig. 1 - Message flow for a full handshakeThe client collects all the handshake messages and signs them with it's private key and sends the result to the server. The server then verifies the signature using the public key of the client certificate. If the signature can be verified with the public key, the server knows the client is in possession of the private key, and is therefore a bona fide user.Let's look at this in the context of our original attack:client attempts to connect to serviceattacker successfully reroutes traffic to a host it controlsmalicious host accepts connection from client accepting the client's certificatemalicious host connects to servicethe malicious host will fail to SSL handshake because the host doesn’t have the private key for the client’s certificate. The attacker therefore cannot compute the correct CertificateVerify handshake message. The CertificateVerify message from the first handshake cannot be used because the handshake sequences diverge (different server certificates presented by the host).Introducing TAuthTAuth is Client SSL Authentication + User Tokens + Great Tooling.Client SSL authentication is often overlooked because of the poor UX of using client certificates in the browser and that generating certificates is a painful multistep process involving arcane OpenSSL CLI incantations. However as we're talking about API clients the browser UX point is irrelevant. As far as certificate generation goes, we can write better tools. These days it's possible to generate a key pair, a PKCS#10 certificate request, and sign it all in the browser. Thanks to WebCrypto the whole process is reduced to one click.This is how Teller does it:A private key and a SSL certificate signed by Teller generated in one click.And this is what a request looks like with client certificates:Let's recap what we've achieved here:Cryptographic proof of the client identityThe cURLability of the API is preservedThe client developer has generated a private key known only to them and no one else, meaning the bank can actually say "you did that transaction" (non-repudiation)Token securityNotice in the above example. The Teller API accepts connections from clients without a client certificate. We do this because we provide developers with read-only personal access tokens for their own accounts if they want to quickly hack something up and not bother with provisioning certs. Now notice how the API does not accept the token presented, but accepts it when used with the client SSL certificate. TAuth bearer tokens are bound on the server side to a private key through an application. This means they are useless without the private key (which only the developer ever has) and therefore not sensitive. As matter of fact, here is one for my bank account:
You'll need the private key it's bound to for it to be of any use, and that has never left my laptop.TAuth tokens do not expire (but can be revoked). OAuth 2.0 introduced the concept of time-limited tokens. Large internet companies found it useful for scaling purposes to issue self-encoded, encrypted tokens. The drawbacks are developers have to pay the complexity cost of refreshing tokens and most importantly tokens cannot be revoked, they're good until they expire. For bank account APIs this is an undesirable property, a token should be void as soon as the account owner wishes. TAuth checks the token revocation status at each request.Given that we have no need for self-encoded tokens and that tokens are useless to anyone without the private key, we can consider them public and directly return them in the callback further simplifying things for the developer compared to OAuth without compromising the user's security.Bonus: DDOS mitigationTAuth can help mitigate layer 7 based DDOS attacks too. If the client does not present a valid client certificate the server can just choose to bounce the connection.ConclusionOAuth 2.0 is simply not fit for use with sensitive APIs and all the pieces needed to build something that is exist today. Aside from unbound bearer tokens, OAuth is too open-ended and complicated to get right for most developers. It's so bad it even has it's own threat model as a separate RFC to offer mitigations for the endless problems that can happen.TAuth stands for Trusted Authentication, and it provides the best security for users while maintaining the highest possible quality developer experience. Less can go wrong when everything is simpler. If your bank has OAuth 2.0 in production you must ask yourself, do they really know what they're doing?TAuth is available in production today for our existing beta users and we've already begun the work to make it an open standard we hope the industry adopts. If you're at a bank and want to offer your customers the security they deserve email me - sg at teller.ioSign up for the beta waiting list at Teller.io.
Dick Hardt
2016-05-11 00:22:36 UTC
Permalink
Let us know what you learn Justin!
Post by Justin Richer
I posted about this the other day. What I don't understand is that he's
saying people disable TLS checks so he's going to solve it with mutual TLS?
I need to email this guy and learn more about what he's doing.
--Justin
*Sent from my phone*
-------- Original message --------
Date: 5/10/16 6:44 PM (GMT-06:00)
Subject: Re: [OAUTH-WG] TAuth
Doesn’t the recent PoP work address many of these concerns?
Also, as for developers disabling SSL — does anyone still do this and
think it’s safe? Or are people just being lazy? Or are there certain
contexts that I’m unaware of where this is valid?
-Brock
Date: Tuesday, May 10, 2016 at 7:24 PM
Subject: [OAUTH-WG] TAuth
Does anyone think there are useful lessons here?
Does adding TOKBIND resolve the issues?
https://blog.teller.io/2016/04/26/tauth.html
*Teller* <https://blog.teller.io/>
Join waiting list <http://teller.io/#waitlist>
Introducing TAuth: Why OAuth 2.0 is bad for banking APIs and how we're
fixing it
This week we released our authorisation flow making it possible for you to
go from building apps that talk to your bank account, to building apps that
can talk to any bank account. This is huge. Check out this SMS bot (how on
trend) I hacked up yesterday morning. (and don't forget to join the beta
wait list <https://teller.io/>).
Getting to this point took longer than we expected. This is because there
wasn't a good story for delegating authorisation for sensitive APIs. The
most popular choice, OAuth 2.0 <http://oauth.net/2> - which has been
chosen by the Open Banking Working Group
<http://theodi.org/open-banking-standard>, BBVA
<https://www.bbvaapimarket.com/web/api_market/bbva/bbva-connect/documentation#3-legged-flow>,
RBS <https://bluebank.portal.azure-api.net/getting-started>, and Mondo
<https://getmondo.co.uk/docs/#authentication> - is also amongst the worst
from a security perspective.
Teller provides an API for your bank account. The EU is forcing all
European banks to expose account APIs with PSD II
<http://ec.europa.eu/finance/payments/framework/index_en.htm> by end of
2017. These banks are disconcertingly converging around OAuth 2.0* without
fully considering the impact on their customers, and something needs to be
done before it's too late.
* One notable exception is the Open Bank Project
<http://www.openbankproject.com/>. It is sticking with OAuth 1.0a
<http://oauth.net/core/1.0a/> precisely because OAuth 1.0a doesn't share
the same security issues as OAuth 2.0.
Man-in-the-middle
One of the biggest problems with OAuth 2.0 is that it delegates all
security concerns to TLS but only the client authenticates the server (via
it's SSL certificate), the server does not authenticate the client. This
means the server has no way of knowing who is actually sending the request.
Is it a bona fide user, or is an attacker tampering with the request? When
an attacker is able to insinuate themselves between a legitimate user and
the server, it's called a man-in-the-middle (MITM) attack. It looks like
- client attempts to connect to service
- attacker successfully reroutes traffic to a host it controls
- malicious host accepts connection from client
- malicious host connects to service
- service accepts connection from malicious host
- client communicates with service proxied through malicious host,
which can see and tamper with any data sent or received
You're probably thinking "hang on, isn't this the point of SSL?" Yes it
is, but there are a number of ways to present a bogus certificate and a
client accept it. The most realistic threat is the client developer not
properly verifying the server certificate, i.e. was it ultimately signed by
a trusted certificate authority?
*Follow* <https://twitter.com/tpope>
<https://twitter.com/tpope>
Pull requests to disable SSL certificate verification: more common than
you would think.
2:24 PM - 11 Feb 2013
<https://twitter.com/tpope/status/301094352434892800>
- 5 5 Retweets
<https://twitter.com/intent/retweet?tweet_id=301094352434892800>5 5
likes <https://twitter.com/intent/like?tweet_id=301094352434892800>
Unfortunately a large <http://stackoverflow.com/a/7332983/223213> number
<http://stackoverflow.com/a/16298999/223213> of developers
<http://stackoverflow.com/a/36154521/223213> think that disabling SSL
peer verification is the correct fix to a SSL path validation error. There
are many more that will offer the same advice with the caveat that it
introduces a security issue <http://stackoverflow.com/a/12293898/223213>
that < 100% of readers will consider. As an API provider with a duty of
care to our users we can't simply hope developers on our platform don't do
this.
Bearer tokens
Once a user authorises a client application to access its account, the
application obtains a bearer token from the authorisation server. As the
name suggests if you have possession of the bearer token then you are
essentially the user. There is no cryptographic proof that the requesting
client is the intended developer and not an attacker. If an attacker is
able to successfully MITM a client it could have catastrophic implications
for the user, e.g. an empty bank account, loans opened in their name, etc.
OAuth 2.0 is simply a security car crash from a bank's perspective. They
have no way to prove that an API transaction is bona fide, exposing them to
unlimited liability.
For more information on OAuth 2.0 shortcomings see OAuth Bearer Tokens
are a Terrible Idea
<https://hueniverse.com/2010/09/29/oauth-bearer-tokens-are-a-terrible-idea/>
and OAuth 2.0 and the Road to Hell
<https://hueniverse.com/2012/07/26/oauth-2-0-and-the-road-to-hell/> by Eran
Hammer <https://twitter.com/eranhammer> the original primary author of
OAuth 2.0 who formally removed his name from the standard, calling it "the
biggest professional disappointment of [his] career."
Finding something better
Sitting down to design the solution to this problem I had two high-level
- be the most secure solution for the user
- not unnecessarily impede developer experience. Developers are users
too and their needs deserve equal consideration.
- cryptographic proof of client identity
- to stop MITM attacks
- to unimpeachably attribute a request to a given developer. In
cryptography this is known as non-repudiation
<https://en.wikipedia.org/wiki/Non-repudiation>.
(N.B. Non-repudiation is a de facto requirement of PSD II. If a bank can't
prove an account owner authorised a transaction, they're liable for any
losses incurred by the user.)
There are solutions to the bearer token problem like JWT tokens (RFC7523
<https://tools.ietf.org/html/rfc7523>) but in most cases these rely on a
shared secret which is used to computed a HMAC-based signature. Shared
secrets mean no non-repudiation. Public key cryptography can be used with
JWT tokens but they don't solve the problem of how the client will generate
key pairs, demonstrate proof of possession of the private key, and enrol
the public key with the API. Most importantly using JWT tokens make it
basically impossible for you to experiment with an API using cURL. A major
impediment to developer experience.
In an ideal world we'd have cryptographic proof of the client's identity
without it having to leak through the application level (and stop us
cURLing the API!). As I thought about it it became the clear the answer was
hiding in plain sight: *SSL client certificates.*
Client SSL Authentication
A SSL handshake involving client certificates contains an extra message at
the end of the handshake, the *CertificateVerify*
<https://www.ietf.org/rfc/rfc2246.txt> message.
Client Server
ClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
Fig. 1 - Message flow for a full handshake
The client collects all the handshake messages and signs them with it's
private key and sends the result to the server. The server then verifies
the signature using the public key of the client certificate. If the
signature can be verified with the public key, the server knows the client
is in possession of the private key, and is therefore a bona fide user.
- client attempts to connect to service
- attacker successfully reroutes traffic to a host it controls
- malicious host accepts connection from client accepting the client's
certificate
- malicious host connects to service
- the malicious host will fail to SSL handshake because the host
doesn’t have the private key for the client’s certificate. The attacker
therefore cannot compute the correct *CertificateVerify* handshake
message. The *CertificateVerify* message from the first handshake
cannot be used because the handshake sequences diverge (different server
certificates presented by the host).
Introducing TAuth
TAuth is Client SSL Authentication + User Tokens + Great Tooling.
Client SSL authentication is often overlooked because of the poor UX of
using client certificates in the browser and that generating certificates
is a painful multistep process involving arcane OpenSSL CLI incantations.
However as we're talking about API clients the browser UX point is
irrelevant. As far as certificate generation goes, we can write better
tools. These days it's possible to generate a key pair, a PKCS#10
certificate request, and sign it all in the browser. Thanks to WebCrypto
<http://www.w3.org/TR/WebCryptoAPI/> the whole process is reduced to one
click.
A private key and a SSL certificate signed by Teller generated in one
click.
- Cryptographic proof of the client identity
- The cURLability of the API is preserved
- The client developer has generated a private key known only to them
and no one else, meaning the bank can actually say "you did that
transaction" (non-repudiation)
Token security
Notice in the above example. The Teller API accepts connections from
clients without a client certificate. We do this because we provide
developers with read-only personal access tokens for their own accounts if
they want to quickly hack something up and not bother with provisioning
certs. Now notice how the API does not accept the token presented, but
accepts it when used with the client SSL certificate. TAuth bearer tokens
are bound on the server side to a private key through an application. This
means they are useless without the private key (which only the developer
ever has) and therefore not sensitive. As matter of fact, here is one for
You'll need the private key it's bound to for it to be of any use, and
that has never left my laptop.
TAuth tokens do not expire (but can be revoked). OAuth 2.0 introduced the
concept of time-limited tokens. Large internet companies found it useful
for scaling purposes to issue self-encoded, encrypted tokens. The drawbacks
are developers have to pay the complexity cost of refreshing tokens and
most importantly tokens cannot be revoked, they're good until they expire.
For bank account APIs this is an undesirable property, a token should be
void as soon as the account owner wishes. TAuth checks the token revocation
status at each request.
Given that we have no need for self-encoded tokens and that tokens are
useless to anyone without the private key, we can consider them public and
directly return them in the callback further simplifying things for the
developer compared to OAuth without compromising the user's security.
Bonus: DDOS mitigation
TAuth can help mitigate layer 7 based DDOS attacks
<https://en.wikipedia.org/wiki/Application_layer_DDoS_attack> too. If the
client does not present a valid client certificate the server can just
choose to bounce the connection.
Conclusion
OAuth 2.0 is simply not fit for use with sensitive APIs and all the pieces
needed to build something that is exist today. Aside from unbound bearer
tokens, OAuth is too open-ended and complicated to get right for most
developers. It's so bad it even has it's own threat model as a separate
RFC <https://tools.ietf.org/html/rfc6819> to offer mitigations for the
endless problems that can happen.
*TAuth stands for Trusted Authentication*, and it provides the best
security for users while maintaining the highest possible quality developer
experience. Less can go wrong when everything is simpler. *If your bank
has OAuth 2.0 in production you must ask yourself, do they really know what
they're doing?*
TAuth is available in production today for our existing beta users and
we've already begun the work to make it an open standard we hope the
industry adopts. If you're at a bank and want to offer your customers the
security they deserve email me - *sg at teller.io <http://teller.io>*
Sign up for the beta waiting list at Teller.io <http://teller.io/>.
_______________________________________________ OAuth mailing list
--
Subscribe to the HARDTWARE <http://hardtware.com/> mail list to learn about
projects I am working on!
Takahiko Kawasaki
2016-05-12 14:11:37 UTC
Permalink
IMHO,

The reason an OAuth 2.0 server does not authenticate _public_ clients is
because, by definition, a public client cannot keep its client secret
confidential and so client authentication is almost meaningless.

"Introducing TAuth: Why OAuth 2.0 is bad for banking APIs and how we're
fixing it" and the famous post "OAuth 2.0 and the Road to Hell" (by Mr.
Eran Hammer) blame OAuth 2.0, but they don't recognize that their
insistence relies on the assumption that a secret key embedded in a client
application can be kept confidential. On the other hand, OAuth 2.0
recognizes that the assumption is naive under some conditions and
explicitly distinguishes confidential clients from public clients (RFC
6749, 2.1. Client Types).

It sounds unconvincing to me that people who live in the 'confidential
client' world blame OAuth 2.0 which covers use cases for both confidential
clients and public clients.

My opinion with further details is written in my answer to the question
"How is OAuth 2 different from OAuth 1?" in StackOverflow.

http://stackoverflow.com/a/35775049/1174054


Best Regards,
Takahiko Kawasaki
Post by Dick Hardt
Let us know what you learn Justin!
Post by Justin Richer
I posted about this the other day. What I don't understand is that he's
saying people disable TLS checks so he's going to solve it with mutual TLS?
I need to email this guy and learn more about what he's doing.
--Justin
*Sent from my phone*
-------- Original message --------
Date: 5/10/16 6:44 PM (GMT-06:00)
Subject: Re: [OAUTH-WG] TAuth
Doesn’t the recent PoP work address many of these concerns?
Also, as for developers disabling SSL — does anyone still do this and
think it’s safe? Or are people just being lazy? Or are there certain
contexts that I’m unaware of where this is valid?
-Brock
Date: Tuesday, May 10, 2016 at 7:24 PM
Subject: [OAUTH-WG] TAuth
Does anyone think there are useful lessons here?
Does adding TOKBIND resolve the issues?
https://blog.teller.io/2016/04/26/tauth.html
*Teller* <https://blog.teller.io/>
Join waiting list <http://teller.io/#waitlist>
Introducing TAuth: Why OAuth 2.0 is bad for banking APIs and how we're
fixing it
This week we released our authorisation flow making it possible for you
to go from building apps that talk to your bank account, to building apps
that can talk to any bank account. This is huge. Check out this SMS bot
(how on trend) I hacked up yesterday morning. (and don't forget to join
the beta wait list <https://teller.io/>).
Getting to this point took longer than we expected. This is because there
wasn't a good story for delegating authorisation for sensitive APIs. The
most popular choice, OAuth 2.0 <http://oauth.net/2> - which has been
chosen by the Open Banking Working Group
<http://theodi.org/open-banking-standard>, BBVA
<https://www.bbvaapimarket.com/web/api_market/bbva/bbva-connect/documentation#3-legged-flow>,
RBS <https://bluebank.portal.azure-api.net/getting-started>, and Mondo
<https://getmondo.co.uk/docs/#authentication> - is also amongst the
worst from a security perspective.
Teller provides an API for your bank account. The EU is forcing all
European banks to expose account APIs with PSD II
<http://ec.europa.eu/finance/payments/framework/index_en.htm> by end of
2017. These banks are disconcertingly converging around OAuth 2.0* without
fully considering the impact on their customers, and something needs to be
done before it's too late.
* One notable exception is the Open Bank Project
<http://www.openbankproject.com/>. It is sticking with OAuth 1.0a
<http://oauth.net/core/1.0a/> precisely because OAuth 1.0a doesn't share
the same security issues as OAuth 2.0.
Man-in-the-middle
One of the biggest problems with OAuth 2.0 is that it delegates all
security concerns to TLS but only the client authenticates the server (via
it's SSL certificate), the server does not authenticate the client. This
means the server has no way of knowing who is actually sending the request.
Is it a bona fide user, or is an attacker tampering with the request? When
an attacker is able to insinuate themselves between a legitimate user and
the server, it's called a man-in-the-middle (MITM) attack. It looks like
- client attempts to connect to service
- attacker successfully reroutes traffic to a host it controls
- malicious host accepts connection from client
- malicious host connects to service
- service accepts connection from malicious host
- client communicates with service proxied through malicious host,
which can see and tamper with any data sent or received
You're probably thinking "hang on, isn't this the point of SSL?" Yes it
is, but there are a number of ways to present a bogus certificate and a
client accept it. The most realistic threat is the client developer not
properly verifying the server certificate, i.e. was it ultimately signed by
a trusted certificate authority?
*Follow* <https://twitter.com/tpope>
<https://twitter.com/tpope>
Pull requests to disable SSL certificate verification: more common than
you would think.
2:24 PM - 11 Feb 2013
<https://twitter.com/tpope/status/301094352434892800>
- 5 5 Retweets
<https://twitter.com/intent/retweet?tweet_id=301094352434892800>5 5
likes <https://twitter.com/intent/like?tweet_id=301094352434892800>
Unfortunately a large <http://stackoverflow.com/a/7332983/223213> number
<http://stackoverflow.com/a/16298999/223213> of developers
<http://stackoverflow.com/a/36154521/223213> think that disabling SSL
peer verification is the correct fix to a SSL path validation error. There
are many more that will offer the same advice with the caveat that it
introduces a security issue <http://stackoverflow.com/a/12293898/223213>
that < 100% of readers will consider. As an API provider with a duty of
care to our users we can't simply hope developers on our platform don't do
this.
Bearer tokens
Once a user authorises a client application to access its account, the
application obtains a bearer token from the authorisation server. As the
name suggests if you have possession of the bearer token then you are
essentially the user. There is no cryptographic proof that the requesting
client is the intended developer and not an attacker. If an attacker is
able to successfully MITM a client it could have catastrophic implications
for the user, e.g. an empty bank account, loans opened in their name, etc.
OAuth 2.0 is simply a security car crash from a bank's perspective. They
have no way to prove that an API transaction is bona fide, exposing them to
unlimited liability.
For more information on OAuth 2.0 shortcomings see OAuth Bearer Tokens
are a Terrible Idea
<https://hueniverse.com/2010/09/29/oauth-bearer-tokens-are-a-terrible-idea/>
and OAuth 2.0 and the Road to Hell
<https://hueniverse.com/2012/07/26/oauth-2-0-and-the-road-to-hell/> by Eran
Hammer <https://twitter.com/eranhammer> the original primary author of
OAuth 2.0 who formally removed his name from the standard, calling it "the
biggest professional disappointment of [his] career."
Finding something better
Sitting down to design the solution to this problem I had two high-level
- be the most secure solution for the user
- not unnecessarily impede developer experience. Developers are users
too and their needs deserve equal consideration.
- cryptographic proof of client identity
- to stop MITM attacks
- to unimpeachably attribute a request to a given developer. In
cryptography this is known as non-repudiation
<https://en.wikipedia.org/wiki/Non-repudiation>.
(N.B. Non-repudiation is a de facto requirement of PSD II. If a bank
can't prove an account owner authorised a transaction, they're liable for
any losses incurred by the user.)
There are solutions to the bearer token problem like JWT tokens (RFC7523
<https://tools.ietf.org/html/rfc7523>) but in most cases these rely on a
shared secret which is used to computed a HMAC-based signature. Shared
secrets mean no non-repudiation. Public key cryptography can be used with
JWT tokens but they don't solve the problem of how the client will generate
key pairs, demonstrate proof of possession of the private key, and enrol
the public key with the API. Most importantly using JWT tokens make it
basically impossible for you to experiment with an API using cURL. A major
impediment to developer experience.
In an ideal world we'd have cryptographic proof of the client's identity
without it having to leak through the application level (and stop us
cURLing the API!). As I thought about it it became the clear the answer was
hiding in plain sight: *SSL client certificates.*
Client SSL Authentication
A SSL handshake involving client certificates contains an extra message
at the end of the handshake, the *CertificateVerify*
<https://www.ietf.org/rfc/rfc2246.txt> message.
Client Server
ClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
Fig. 1 - Message flow for a full handshake
The client collects all the handshake messages and signs them with it's
private key and sends the result to the server. The server then verifies
the signature using the public key of the client certificate. If the
signature can be verified with the public key, the server knows the client
is in possession of the private key, and is therefore a bona fide user.
- client attempts to connect to service
- attacker successfully reroutes traffic to a host it controls
- malicious host accepts connection from client accepting the
client's certificate
- malicious host connects to service
- the malicious host will fail to SSL handshake because the host
doesn’t have the private key for the client’s certificate. The attacker
therefore cannot compute the correct *CertificateVerify* handshake
message. The *CertificateVerify* message from the first handshake
cannot be used because the handshake sequences diverge (different server
certificates presented by the host).
Introducing TAuth
TAuth is Client SSL Authentication + User Tokens + Great Tooling.
Client SSL authentication is often overlooked because of the poor UX of
using client certificates in the browser and that generating certificates
is a painful multistep process involving arcane OpenSSL CLI incantations.
However as we're talking about API clients the browser UX point is
irrelevant. As far as certificate generation goes, we can write better
tools. These days it's possible to generate a key pair, a PKCS#10
certificate request, and sign it all in the browser. Thanks to WebCrypto
<http://www.w3.org/TR/WebCryptoAPI/> the whole process is reduced to one
click.
A private key and a SSL certificate signed by Teller generated in one
click.
- Cryptographic proof of the client identity
- The cURLability of the API is preserved
- The client developer has generated a private key known only to them
and no one else, meaning the bank can actually say "you did that
transaction" (non-repudiation)
Token security
Notice in the above example. The Teller API accepts connections from
clients without a client certificate. We do this because we provide
developers with read-only personal access tokens for their own accounts if
they want to quickly hack something up and not bother with provisioning
certs. Now notice how the API does not accept the token presented, but
accepts it when used with the client SSL certificate. TAuth bearer tokens
are bound on the server side to a private key through an application. This
means they are useless without the private key (which only the developer
ever has) and therefore not sensitive. As matter of fact, here is one for
You'll need the private key it's bound to for it to be of any use, and
that has never left my laptop.
TAuth tokens do not expire (but can be revoked). OAuth 2.0 introduced the
concept of time-limited tokens. Large internet companies found it useful
for scaling purposes to issue self-encoded, encrypted tokens. The drawbacks
are developers have to pay the complexity cost of refreshing tokens and
most importantly tokens cannot be revoked, they're good until they expire.
For bank account APIs this is an undesirable property, a token should be
void as soon as the account owner wishes. TAuth checks the token revocation
status at each request.
Given that we have no need for self-encoded tokens and that tokens are
useless to anyone without the private key, we can consider them public and
directly return them in the callback further simplifying things for the
developer compared to OAuth without compromising the user's security.
Bonus: DDOS mitigation
TAuth can help mitigate layer 7 based DDOS attacks
<https://en.wikipedia.org/wiki/Application_layer_DDoS_attack> too. If
the client does not present a valid client certificate the server can just
choose to bounce the connection.
Conclusion
OAuth 2.0 is simply not fit for use with sensitive APIs and all the
pieces needed to build something that is exist today. Aside from unbound
bearer tokens, OAuth is too open-ended and complicated to get right for
most developers. It's so bad it even has it's own threat model as a separate
RFC <https://tools.ietf.org/html/rfc6819> to offer mitigations for the
endless problems that can happen.
*TAuth stands for Trusted Authentication*, and it provides the best
security for users while maintaining the highest possible quality developer
experience. Less can go wrong when everything is simpler. *If your bank
has OAuth 2.0 in production you must ask yourself, do they really know what
they're doing?*
TAuth is available in production today for our existing beta users and
we've already begun the work to make it an open standard we hope the
industry adopts. If you're at a bank and want to offer your customers the
security they deserve email me - *sg at teller.io <http://teller.io>*
Sign up for the beta waiting list at Teller.io <http://teller.io/>.
_______________________________________________ OAuth mailing list
--
Subscribe to the HARDTWARE <http://hardtware.com/> mail list to learn
about projects I am working on!
_______________________________________________
OAuth mailing list
https://www.ietf.org/mailman/listinfo/oauth
Loading...