The recent compromise of Sony’s PlayStation network has been getting a fair deal of coverage in the news, not least because of the escape of credit card details. I’m not a PlayStation user so this doesn’t affect me directly, but it got me thinking. Generally speaking, the best way to ensure your customers data cannot be leaked is not to have it in the first place. It’s this principle which protected LastPass and their customers from a much greater scare when they recently published a warning of the risk their database may have been hacked. LastPass is an online password management service which stores customers password data on their servers. Except LastPass stores users data in an encrypted blob which LastPass never sees the password too, thus they cannot accidentally reveal. So how can this principle be applied to that most precious of personal details - credit card details.
Presumably the reason Sony, like many other companies, stores card details in the first place is such that they can take re-occurring subscription payments or simplify purchasing within their network (as I say, I’m not a PlayStation user). This feels like a pretty crude solution to the problem. The problem, and the solution which comes to my mind, are reminiscent of web services which require access to each other and do so by storing user names and passwords for the accounts they need to access. An example of this might be some service which needs to send email on behalf of a user. This approach has several downsides. Firstly, once granted, access is irrevocable without a password change. If a user decides they no longer want a service to have access to their mail, the only way to be 100% sure it no longer does, is to change the mail password, requiring all mail clients and any other services which a user does wish to continue accessing it to be updated. Secondly, each service which stores credentials for another service is increases the number of places hackers could find those details, thus significantly increasing the risk that they will. Returning to the issue of payments, credit card details are analogous to the user name and password of the service others wish to access, with the unfortunate difference that they are more inconvenient to change and more important to keep safe.
But what’s the alternative? In the case of inter-service authentication, one solution which greatly improves upon the situation has been OAuth. OAuth removes the need for consuming services to have the user-name / password for a service they wish to authenticate with. This is achieved by users granting access from a service to consumers by the issuing of some sort of cryptographic tokens from the target service, which the consuming service can then store, and use to authenticate with the target service in future. These tokens are specific to the service requesting access and are essentially signed by the issuing service so that they cannot (reasonably) be faked. Furthermore, services supporting this authentication will provide an interface by which users can block tokens and thus revoke access to the consuming services they have been issued to.
I should make clear at this point that I have no experience of either banking, e-commerce or OAuth, so my standard disclaimer on ignorance is especially applicable. That said, it seems to me, that a similar approach could be applied to authenticating financial transfers. Rather than hand out credit card details to services which require repeated access to our finances we would be redirected to our bank, with whom we would authenticate, and then authorise limited access to our funds to another account. This authorisation would take the form of a token, essentially signed by our bank account which could be stored by the requesting service. This service would then present this token to authenticate payments from us. This would seem to have the benefits that OAuth brings. If the service accessing our money was compromised, the tokens in its database would be useless to attackers since they would be tied to a specific recipient account - much like a cheque. Furthermore if we wished to remove access to our funds from a service we could cancel the token with our bank.
Perhaps an even simpler solution along the same lines would be for our banks to let us generate sets of payment card details which are tied to a given recipient account. Under this system we would log on to our bank, and generate a “card” tied to the service we wish to pay. Our bank would then only authorise transfers to the designated account using those card details. This has the advantage that the site or service requesting our card details need not implement any complex system, but could continue to ask for our card details as before, yet these details would be relatively useless if lost, and could be easily revoked.
Since I’ve not spent that long thinking about this, I suspect both ideas are either already in existence, or fatally flawed in some obvious way I’ve not yet spotted. Hopefully not both! No doubt I’ll realise this as soon as I hit post.
Software Engineer with over 12 years experience shipping solutions in node.js, Typescript, Elixir, C#, and C++