There are many web-based services that ask for online banking credentials in order to verify a user's bank account. For example, Coinbase and TransferWise ask the user to provide their banking username and password in plaintext.
I've come up with a way for a user to verify their bank account details without ever providing their username and password to a third party. I would like to know if there are any security flaws with the following protocol:
- The third party service starts a proxy server that records all traffic.
- The user establishes a TLS connection through the proxy, and verifies the bank's SSL certificate.
- The user signs in using their username and password, and saves their session cookie.
- The user starts a new TLS connection through the proxy, which uses a different master secret.
- The user uses their current session cookie to fetch their account details through the proxy.
- The user signs out and invalidates the session cookie.
- The user sends the final TLS connection's master secret to the third party service.
- The third party service is now able to decrypt the HTML and verify the user's details, such as their full name, phone number, and account balances.
Notes:
- If a bank allows a session cookie to be used from multiple IP addresses, the user could just sign in and out on their own machine.
- The user would be viewing the proxied pages on their own machine, so this would also work with two-factor authentication.
- Some online banking websites may not properly invalidate session cookies when a user signs out. However, most (if not all) banks expire a session after 10-15 minutes of inactivity, so the user can just wait for the session to expire before revealing the private key.
- The page HTML could leak more data than necessary. There would be various ways to solve this for different banks. Many banks provide an API for their mobile apps, so you could just proxy some specific API requests to only reveal the necessary information.
- Instead of sending the private key and allowing the third-party to decrypt the whole page, it might be possible to create a garbled circuit that produces a zero-knowledge proof. The garbled circuit would first decrypt the page, then it would only return true if the account details match and the account balance is within a certain range.
One way to implement this might be to create a WebKit-based browser application that users can download and install. The app could set up a protocol handler in their browser, so that the app opens whenever the user clicks on a URL like <verification scheme>://domain/path
. The app would work with any website, but it could also use preconfigured recipes for different banks.
This could also be implemented directly in Firefox and Chrome, but that's not very likely. There's also much better ways to do this. Some modern banks can provide an OAuth token with limited read-only permissions. A bank could even use public key cryptography to just sign your account details using their private key (maybe the private key for their current SSL certificate.)
I think the technique described above might be useful, since it can work for any website (not just banking.) But please let me know if you can spot any security issues here. I'm sure I've misunderstood something about TLS, or maybe there's an even easier way to do this.