Profile picture
John Backus @backus
, 22 tweets, 8 min read Read on Twitter
If you are using an in-browser Ethereum wallet (e.g. Metamask, Brave, Parity) then any website can detect if you are an Ethereum user. I wouldn't be surprised if some advertisers are already collecting this information.
Metamask and Parity inject a global web3 object into the page. For example, the attached screenshots show Metamask and Parity both injecting web3 into the page I'm tweeting from. Parity even exposes the current account address by default.
These websites can't send transactions on your behalf of course (not without popping up a confirmation window) but do you really want any website owner or advertiser to know that you hold crypto? Do you want them to know how much ETH you own?
Even though Metamask is locked by default (meaning public addresses aren't exposed) it is trivial to listen for a wallet unlock. When you unlock your Metamask wallet, it unlocks it across all tabs. Attached gif is an example app that alerts when it detects a wallet unlock.
Detecting an unlock from an unfocused tab is especially sketchy in my opinion. This means any app can detect when you are in the middle of *using* your Ethereum wallet.
If the user just unlocked their wallet for another tab then they are probably about to send a transaction. The attacker can detect the unlock, wait 30 seconds, then pop up their own transaction. Attached gif is an example attack when the user is in the middle of using an exchange
A lot of other small attack opportunities IMO that exist as long as web3 is injected into every page. You can tell if someone is specifically a Metamask user by checking `web3.currentProvider.isMetamask`. Why not pop up your own Metamask lookalike in the top right?
Regardless of whether the wallet is currently locked, you can use the current network id on web3 to see if the user was last using the testnet or mainnet. If they're on anything besides mainnet, they are probably a developer and likely have higher than average crypto holdings.
To give Metamask credit, they do have several issues on Github open discussing issues around globally available web3 instance:

- github.com/MetaMask/metam…
- github.com/MetaMask/metam…
- github.com/MetaMask/metam…
- github.com/MetaMask/metam…
In my opinion, the best immediate stopgap these extensions should add is something similar to other browser permissions like how we grant access to location information.

I think the Metamask team is looking into doing this long term: github.com/MetaMask/metam…
Potential short term solution:

1. Hardcode that only metamask.io/whitelist can call invoke some whitelist functionality in extension
2. dApps opens popup for metamask.io/whitelist?url=…
3. Extension asks if you want to give example.com access to your wallet
Restricting this functionality to their domain means that nothing has to be injected into every page. Popup means any page can really easily initiate the whitelist process without having to write browser vendor specific extension interactions.
Short term solution would then be to add whitelisting as an opt-in feature (so you don't break existing integrations and make people regret writing their app to depend on Metamask). Security conscious users can opt-in right away and app developers can plan for deprecation.
In the meantime, I'd recommend users disable Metamask by default in their browser and then enable it when they want to use it. Unlike unlocking a wallet, I wasn't able to detect (from an already open and unfocused tab) when a disabled extension was enabled.
Some UI improvements would also help the transaction spoofing example I gave. The browser should switch to the tab that created the transaction. The confirmation window should probably have a brightly colored banner that says "example.com created this transaction."
Metamask and other browser wallets are in a tough position though with these transaction popups. If a legitimate dApp could put a custom message in the confirmation window then an attacker could mimic it.
I'd love to see is the ability to use an ENS address as the recipient field in a transaction. For @BloomToken, users are currently interacting with one of two contracts. If our end users saw our ENS address for every transaction then they'd be less likely to fall for a spoof.
I also want to clarify that I'm not saying that people should never use these in-browser wallets. Security is especially tough and nuanced when you are a platform for handling money and user identity. Even harder when you are on the development side of early adoption.
In-browser wallets should be unlocked *per domain*. An advertiser shouldn't be able to log my ETH address in an unfocused tab just because I want to check on my crypto kitties.
I'd also love to see at least an opt-in setting that locks my wallet again after sending a transaction. If a dApp wants to send multiple transactions without unlocking between each, they can use `web3.createBatch`. Metamask handles this well already
An attack that sent ERC20 tokens would be effective. Unlike moving ETH (where Metamask would say how much ETH you are sending), a token transaction would just display the gas price AFAIK. More likely to trick people if they can't tell what is being sent.
If you enjoyed this thread on in-browser wallet security, I started a separate thread about community security when running a token sale:

Missing some Tweet in this thread?
You can try to force a refresh.

Like this thread? Get email updates or save it to PDF!

Subscribe to John Backus
Profile picture

Get real-time email alerts when new unrolls are available from this author!

This content may be removed anytime!

Twitter may remove this content at anytime, convert it as a PDF, save and print for later use!

Try unrolling a thread yourself!

how to unroll video

1) Follow Thread Reader App on Twitter so you can easily mention us!

2) Go to a Twitter thread (series of Tweets by the same owner) and mention us with a keyword "unroll" @threadreaderapp unroll

You can practice here first or read more on our help page!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just three indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member and get exclusive features!

Premium member ($3.00/month or $30.00/year)

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!