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 <[email protected]> on behalf of Dick Hardt 
<[email protected]>
Date:  Tuesday, May 10, 2016 at 7:24 PM
To:  Oauth Wrap Wg <[email protected]>
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.
>From a security perspective I wanted:
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 
[email protected] https://www.ietf.org/mailman/listinfo/oauth
_______________________________________________
OAuth mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/oauth

Reply via email to