How The TezBox Wallet Audit Should Inform How We Think About Privacy
The TezBox team promptly resolved all issues discussed here. If you want to skip my rambling and just read the official report, it’s here.
Last September, I had the pleasure of performing a security audit for a Tezos project called TezBox, developed by Stephen Andrews. TezBox is a web based digital wallet for using the Tezos cryptocurrency. I’m always excited to audit JavaScript projects, especially those that run in the browser and secure your finances, because the browser is a hostile place and JavaScript is not generally the best language for writing financial applications due to its type system and number precision idiosyncrasies.
Generally when auditing projects like this the primary focus is around subverting the protection of private keys, manipulating transactions before they are signed, and other problems that can lead to theft or loss of funds. And make no mistake, I was able to do those things during this audit and we’ll get to that. But more alarming though, was not that these “features” existed in TezBox, but rather that these features are seen widely across many web wallets and are viewed as crucial to their user experience! Perhaps most frightening was that some design choices that were clearly viewed as features by the project team actually had some pretty devastating privacy implications.
Do you like scary stories?
Imagine a world where every website you visit can look at every financial transaction you have ever made. Applying for health coverage? Sorry, your financial history indicates you won’t be able to cover the premium. Need a loan? Unfortunately your spending habits have triggered a flag in our risk management system. Looking for a job? Well, judging from your past income, we cannot offer you the salary you requested.
Now this may seem like hyperbole, but hear me out: how often do you hear phrases like “blockchain is the future”, “cryptocurrency will replace centralized banking”, or “something something fiat something federal reserve something liberty”? For an industry that at large seems to pride itself on being more private, secure, and empowering than the existing financial institutions there sure is a lot more focus on user experience than actually being more secure or private. Say what you want about my local credit union’s online banking site, but I can safely browse the internet without revealing to websites my potentially unhealthy compulsive purchasing of pattern printed leggings.
And don’t get me wrong, I get it. We want users to adopt our (barely working and grossly inefficient) financial technologies first, then fix all the problems later. But, we have an ethical duty to ourselves and each other to ensure that we aren’t setting ourselves up for a dystopian future where social credit exists as some kind of terrifying real life proof-of-stake system. We have to put privacy first and design our user experiences around those requirements — not the other way around.
Okay, but what was the actual problem?
The anti-feature that I’m referring to is probably familiar to you if you use a cryptocurrency wallet that exists as a browser extension. Extensions are a different animal than a regular web application, because they have elevated permissions. They can do stuff that web applications cannot, such as interacting with the file system, making cross origin network calls, talking to other open tabs, etc. A common way that we see extensions make their functionality available to “normal” web sites is by injecting a script into every page that provides an interface for controlling some features of the extension.
In the case of cryptocurrency wallets that live in a browser extension, some common features we often see are getting the user’s public key or triggering a transaction confirmation dialog for making a purchase. The idea behind this is to allow e-commerce sites to incorporate a “smooth” experience for making purchases. On the surface this might sound reasonable. After all, a public key cannot be used to steal funds and the convenience of clicking “check out” and having a prompt pre-filled with the address (which, to people who are not cryptographers, is nonsense gibberish) and the amount is probably really attractive to those seeking to make it “easy for Grandma”.
Now there are two particular issues here that basically arise from the same core problem: trust. The extension indiscriminately allows any web page to interact with it, without any authorization from the user. The first problem I want to dive into is about exposing public keys to any site that requests it.
Taping your bank statement to your back and going to the mall
Public keys are kind of a big deal when it comes to cryptocurrency, because without them it would not be possible for untrusted third parties to verify transactions are valid. The problem with the language of “public” is that it encourages the assumption that it doesn’t matter who knows it. But this is not true. While these systems inherently rely on public keys being known to everyone, connecting a public key to a real world identity (email, handle, real name) allows whoever makes such a connection to identify every transaction ever made by that user. This is not like traditional banking where an account number alone cannot be used to discover transaction history. This is what I mean when I say that if cryptocurrency is ever going to replace traditional finance, we need to be putting privacy at the forefront of our designs.
In addition to any specific site being able to read private fincancial data (private in the sense that it is now connected to you), there is another element to very seriously consider: device fingerprinting. For the uninitiated, this is a process by which your device can be differentiated from other devices using a number of techniques such as checking fonts you have installed, screen size, user agent, extensions installed, operating system, and other information that you carry around with you on the internet. The Electronic Frontier Foundation has a tool to demonstrate this black magic that trackers use to follow you around called Panopticlick. Try it and see what I am talking about.
Let me draw a parallel. Did you know that everytime to see a Facebook “like” button or a Twitter “tweet” button on a webpage that those respective companies know you’ve been there? This is how these companies build complex profiles on you and why their partners pay them for targeted advertising. Our exposed public key problem compounds this gross violation of privacy. Now your browsing habits and spending habits can be cross-correlated. Danger zone, friends.
Like the pop-up advertisements of the old web, but now they can take your money
Taking a step back now from the privacy implications, I want to look at the other big issue with allowing any web page to trigger actions within a cryptocurrency wallet. In the case of TezBox (and many other browser extension wallets), websites could trigger two types of dialogues from the wallet: transactions and signing arbitrary messages.
Remember back in the early 2000's? You’re doing some fierce fantasy role playing over AIM in the middle of the night on your Grandmother’s 56k dial up connection. (You needed something to do while those low resolution desktop wallpapers slowly downloaded). You’re clicking around all willy-nilly and suddenly a small window appears asking you to download talking cursors or something. For a moment, you hesitate to consider that maybe you do want to download that. Instead, you close the window. But, another appears in its place. And another. You can’t get rid of them! Soon popups cover your screen and as you frantically attempt to close them you accidentally miss that little “X” button and instead click inside the window, permanentely adding Grandma’s computer to a botnet that is periodically rented to foreign intelligence agencies and the mysterious hacker known as 4chan.
So, I found a bug like this in the TezBox wallet (minus the role playing and stuff). Since any web page was able to trigger these dialogues and there was no prevention from triggering more than one at a time, any web page could open a hundred transaction dialogues and hope while trying to close them, the user accidentally hits “send”. The transaction dialogues were prefilled with your entire balance, because the attacker knew your public key and was able to learn exactly how much to take. Check out Issue C in the complete report for more details.
The same scenario was possible for signing any arbitrary message, which includes not just transactions, but also other actions within the Tezos network such as voting on consensus rules. Does it seem too farfetched that this type of social engineering could be used to subvert the governance system in the Tezos network? I’m not sure it’s worth the risk of finding out.
Privacy at the center of user experience
Earlier in this write-up I implied that these issues are not necessarily the result of negligence or ignorance, but rather the manner in which we approach user experience. The TezBox team responded quickly to these issues, mitigating them by simply removing the offending code (at our recommendation). But, I do think there is a happy medium here and touch on this a little bit in the remediation section of Issue C in the report.
I mentioned that the core issue here is around trust. The wallet simply trusted any web site and allowed it to trigger these actions and gain information. I do think that there is value in these features. It’s easy to make mistakes when typing or copying a cryptocurrency address, so the idea of letting merchants pre-fill and trigger payment dialogue is great. So, how do we prevent unwanted sites from interacting with the wallet?
Personally, I like the idea of allowing sites to trigger a permission dialogue. The user is confronted with making a decision to allow a site to interact with the wallet and when browsing a site that has this permission granted, showing an indicator that this site has these permissions. This brings the issue of privacy to the center of the user experience and trains users to think about who has access to their public key and can trigger payment dialogues.
This is what I mean when I say that we need to be approaching user experiences in a way that brings attention to privacy by training users to expect choice and control when it comes to their information. If we can reshape what users expect from applications and service providers, users will begin to demand this type of control and everyone wins (well, everyone except for the surveillance capitalists).
What about the other stuff you found?
Oh right! This was a pretty fun audit in that there were some pretty critical issues aside from what was mentioned here already. These issues are worth reading about in the full report. I won’t dig into them here because they aren’t relevant to my agenda of ranting about privacy and user experience.
Let me remind you that while the issues covered here were discovered while conducting a security audit of TezBox, they are not unique. Similar anti-features exist in most cryptocurrency wallets that are browser extensions. The TezBox team very promptly resolved all of the issues we reported. I hope that other developers will follow their example and take these issues around privacy and user experience seriously.
If you have any questions or comments about the TezBox Audit, please don’t hesitate to reach out to us: contactus@leastauthority.com.