Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we please stop broadcasting user addresses? You can't use MetaMask for a health or porn based dApp #6325

Closed
projectoblio opened this Issue Mar 20, 2019 · 10 comments

Comments

Projects
None yet
5 participants
@projectoblio
Copy link

projectoblio commented Mar 20, 2019

At the most basic level the fact that you have an ETH address which is broadcasted to every single site and tracker can be used to increase the prices you see on sites like Amazon, Google, and others.

At the middlemost levels it tracks what kind of porn you watch on SpankChain and any other dApp that requires privacy to function, like a health or neuroscience based dApp. Even transferring ETH between accounts still links you back to your last known identity (which is linked to your MetaMask account) and can be used to change your rates on employment opportunities, health insurance, loan risk factors, etc based on your proclivities or health metrics.

At the highest levels it prevents you from being able to convert ETH to fiat without significant delays.

At the inception levels it sacrificies the privacy of everyone in the system because sites like Amazon, Google, PayPal, and others can link your blockchain transactions to credit card payments, thereby your identity, and the identity of the last person you transacted with -- a person who wants to remain anonymous. These identity networks can be used to identify you based on social circles. Just enabling private mode doesn't do very much at all to prevent this.

I am talking specifically about message broadcasts, not the window object which has been brought up by others. To see the message broadcasts, go to any page, open the console, and type in this code: window.addEventListener("message",function(e){console.log(e.data)}). About every 40 seconds, you'll see a message with target:inpage that contains a data object which contains your ETH address. These message broadcasts are worse than window objects because they can be picked up by any advertisement or tracker or youtube player (facebook like buttons, etc) and otherwise serve no purpose. There are plenty of other ways to interact with a chrome extension aside from communicating unique identifiers to these other companies, and they do not have anything to do with injected web3.

For example, if there really are any legacy dApps that rely on these message broadcasts (highly doubtful, would love to see), new installations of MetaMask could by default send the burn address: 0x00000000000000000 instead of a unique identifier in these message broadcasts. As suggested in a recent recent issue, users can enable their address to be broadcasted on a per-site basis (per dApp), which would change the address from the 0 address to their personal address.

These message broadcasts will significantly decrease the value of ETH over the long-term.

@projectoblio projectoblio changed the title Deceitful MetaMask still broadcasting user addresses despite claiming over 4 months ago it had stopped Can we please stop broadcasting user addresses? You can't use MetaMask for a health based dApp Mar 20, 2019

@projectoblio projectoblio changed the title Can we please stop broadcasting user addresses? You can't use MetaMask for a health based dApp Can we please stop broadcasting user addresses? You can't use MetaMask for a health or porn based dApp Mar 20, 2019

@projectoblio

This comment has been minimized.

Copy link
Author

projectoblio commented Mar 20, 2019

Using window messages in this way is * f'd up*. It's not just a cryptocurrency problem. MetaMask is communicating unique identifiers to every frame on every website you visit. You can track users across VPNs, firefox private windows, even different devices. You should not, for example, be using BitMex from the US with MetaMask installed, because BitMex could buy metamask leakage data from practically any website on the web that might be collecting it and determine you're primarily US based, and halt your withdrawals until you provide a license or passport. That's the financial incentives at play here. And they'd probably be right

This is a major security hole in metamask that should not be ignored.

@projectoblio

This comment has been minimized.

Copy link
Author

projectoblio commented Mar 20, 2019

Also please see their deceitful medium post here where they say in the headline that Private Mode will be enabled by default on November 6th:

https://medium.com/metamask/https-medium-com-metamask-breaking-change-injecting-web3-7722797916a8

Please see earlier issue which was much angrier and filed 22 days ago and still ignored.

You should not be trusting deceitful wallet software. Would you trust a deceitful exchange? MetaMask is being sketchy in an industry known for hacks -- I have filed multiple issues now and i am telling you, the only reason for broadcasting unique identifiers would be for shady stuff

@danjm

This comment has been minimized.

Copy link
Contributor

danjm commented Mar 21, 2019

@projectoblio So are you seeing your address in the data logged by window.addEventListener("message",function(e){console.log(e.data)}) even after private mode is enabled?

I just did the following:

  • freshly installed metamask (and noticed that privacy mode is not enabled by default)
  • opened the console here on github and entered window.addEventListener("message",function(e){console.log(e.data)})
  • saw the data logged as you described, with my ethereum address and selected network
    Screenshot from 2019-03-21 13-06-12

Then I:

  • turned on privacy mode
  • refreshed the tab where github was open
  • opened the console on the github tab and entered window.addEventListener("message",function(e){console.log(e.data)})
  • saw that the logged data no longer contains my address
    Screenshot from 2019-03-21 13-04-24

Are you seeing something different when you do the same @projectoblio? If so, would you be able to go to the info tab of the settings screen and tell us what version of MetaMask you are on?

If you are seeing the same behaviour, and privacy mode does cause the address in the message data to be undefined, then am I correct in concluding that your concerns will be addressed by having privacy mode enabled by default?

@projectoblio

This comment has been minimized.

Copy link
Author

projectoblio commented Mar 21, 2019

You don't have a technical reason for doing these message broadcasts, or an example of a dApp that relies on them. Please show me a dApp that breaks when only these message broadcasts are disabled (not the injected web3 object, which cant be detected by the same kinds of trackers)

This is not about my own personal use; It's about responsible dApp design. I will launch my health dApp with my own wallet software. I will require users to uninstall MetaMask and explain to them why: Because any past or future website action they've already made with MetaMask before private mode is linked to a global identifier that will tie them to transactions they send to my dApp, and because the software team is deceptive. Thanks for motivating me to do so.

@danfinlay

This comment has been minimized.

Copy link
Contributor

danfinlay commented Mar 21, 2019

The primary security feature that MetaMask offered Ethereum users was to allow them to stop leaving keys in websites that they don't trust. We did this by using the WebExtension API to store the keys in the background.

In order to provide an API to websites, we have to communicate via a per-page content script. Content scripts can unfortunately only communicate with individual pages via the Post Message API, which can be heard by all elements in the connected site.

We do agree that:

  • We need to enable privacy mode by default, and have been slow to do that. We'll be doing this soon, but are making sure to do it in a non-site-breaking way.
  • PostMessage does expose the messages to all elements within a signed-in iFrame, and that could be more private. However, we depend on browser developers to make a more private communication channel for providing an API to sites.

We definitely reject all your claims that this is some weird malicious act on our part. That would be the craziest move we could ever make on a totally open source crypto project.

Our action items are the same they were the last time you posted: To get to privacy mode by default sooner.

If you have a proposed mechanism for providing an API to a site from an extension that is more private than PostMessage, we would be happy to see it. By all means let us know if you find a better way for your own wallet, we are being completely transparent about our reasoning here.

@danfinlay danfinlay closed this Mar 21, 2019

@projectoblio

This comment has been minimized.

Copy link
Author

projectoblio commented Mar 21, 2019

Dude the problem isn't postMessage. It's the postMessage of unique identifiers (the ethereum address) that doesn't need to happen until a website has replied with their origin, and if the user has authorized the website with that origin. There's literally no reason for these unique identifiers to be posted on every single website by default, for any dapp. There's like a billion other ways to communicate messages (e.g. time-dependent encryption) that can be used to communicate this value so that it's unique every time or at least doesn't link at all to an Ethereum address

if(typeof window.ethereum!="undefined"){
         // dApp  message to content script
         // etc 
}

The window object can't be accessed by iFrames so it hardly matters as much. The post message functionality is what's sketchy.

I'm not here to be 🔥🔥🔥. If you were me and we had never met in real life, you would respond the same way

Edit: Next comment was deleted but is in your email

@danfinlay

This comment has been minimized.

Copy link
Contributor

danfinlay commented Mar 21, 2019

There's literally no reason for these unique identifiers to be posted on every single website by default, for any dapp.

We agree, this is what we call "privacy mode", and you can enable it in settings now as danjm wrote above, and we are working to make it default without breaking existing sites.

There's like a billion other ways to communicate messages (e.g. time-dependent encryption) that can be used to communicate this value so that it's unique every time or at least doesn't link at all to an Ethereum address

I'd love to hear more about these billion other ways. Communicating these proposals would probably be easier than building a wallet from scratch.

One way we're considering improving this privacy story is by generating a single-purpose key per app, but this is still in an early proposal phase:
https://ethereum-magicians.org/t/eip-erc-app-keys-application-specific-wallet-accounts/2742

We aspire to make MetaMask not just hold up to any legally-enforced privacy standards, but to raise the bar of privacy.

We'll be enabling privacy mode by default soon(er), the criticism that we've been slow on that is valid and we take it seriously. (we will allow backwards compatibility for users who want to manually enable the old behavior)

We will still require a way to communicate with logged-in apps, and that means over PostMessage, and that means all your dependencies will still be able to listen to post messages to hear update messages. It's an interesting question of whether we could establish a secure communication channel with an application that excludes other scripts it loaded in the same domain. I'm not clear why a time-generated key would not be prone to a dependency generating the same key. It probably requires the site generating its own key, and then at log-in time somehow validating that the site currently requesting sign-in permission is in fact the key generated by the app you intended to connect to, not by any of its dependencies which also have access to this global ethereum.enable() method. Maybe either a CA or Web of Trust type infrastructure could do, but then either the log-in requires the site to host a live server with the key (which eliminates statically hosted Dapps), or the key is publicly known, and in turn available to dependency or other-site phishing attacks.

Anyways, we're all ears on how we could make that communication channel more private, although it still seems like the privacy mode we keep talking about, that you keep dismissing, might satisfy your criteria.

@projectoblio

This comment has been minimized.

Copy link
Author

projectoblio commented Mar 21, 2019

The post message function includes an input to specify which domain receives the message. It is a security field called cross origin research sharing (CORS). It is designed for exactly this issue.

I didn't study CS in high school or college so i dont know if this is something people know about but i assumed it was. Perhaps this is our disconnect

CORS prevents iFrames from google, facebook etc from accessing the window object, including the ethereum object. That's why i'm trying to explain how these are two separate issues. Message broadcasts are a loudspeaker that can be picked up by iframes; a window object cant. A window object is already assumed by most devs to be vulnerable to a javascript-only script tags.

@nsjames

This comment has been minimized.

Copy link

nsjames commented Mar 21, 2019

One of the ways we are doing this is by creating appkeys, nonces and internal user-approved permissions with origins that are specific to apps themselves and requiring "logins" to websites before exposing any private data like keys/addresses/accounts and such. We're also using local socket layers for connections which helps go from app -> wallet instead of wallet -> app.

However, @projectoblio I think you're missing one of the more important parts that @danfinlay is mentioning here. We had the benefit of learning from MetaMask's journey and implementing that kind of stuff off the bat at the core of the code-base.
MetaMask is an existing project with a vast number of applications that tie into it already and doing things on such an integrated stack requires lightly treading to make sure that applications that rely on it don't break.

Making drastic changes that might break functionality of accustomed user flows could end up costing both businesses and users tens of millions of dollars, and those decisions can't be taken lightly. Testing phases as secondary options is the proper way to do things when dealing with applications at this scale.

@ashaffer

This comment has been minimized.

Copy link

ashaffer commented Mar 25, 2019

In order to provide an API to websites, we have to communicate via a per-page content script. Content scripts can unfortunately only communicate with individual pages via the Post Message API, which can be heard by all elements in the connected site.

I believe his point is that the postMessage API allows you to restrict the target origin of the messages that you are broadcasting, but you are not taking advantage of that to narrow the scope of availability of those messages. This would, e.g. prevent tracking iframes from intercepting these messages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.