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

Draft dapp html transaction authorization without CORS #107

Merged
merged 19 commits into from
Apr 19, 2017

Conversation

wighawag
Copy link
Contributor

@wighawag wighawag commented May 9, 2016

No description provided.

@wighawag wighawag changed the title Draft dapp html authorization Draft dapp html transaction authorization without CORS May 10, 2016
@danfinlay
Copy link
Contributor

Nice proposal, thanks for thinking about user security, I think it's an important concern.

First of all, the introduction is slightly deceptive. Users would still need to enable CORS. The benefit (as I see it) would be that the node would not need to run in account-unlocked mode, giving the user a chance to decline transaction requests.

Couldn't this also be done with a middleware server in front of the RPC, that would hold the accounts, and do the signing? It seems like a fine architecture for a type of wallet, but I'm not sure I see the benefit of formalizing it into an RPC specification, since actually it's just about different account unlocking behavior, and there isn't any requirement for that account unlocking to be part of the RPC, and not part of some other wallet architecture.

From the app perspective, they're still just submitting sendTransaction, and it's just about providing new ways for the user to approve those transactions, that are better than the current default RPC account unlocked methods.

I see this mostly as a cultural proposal. We should stop asking users to run RPC nodes in account unlocked modes. Users should use wallet software or middleware to connect to unauthenticated RPCs, and should use that wallet software to regulate signatures. If some RPC servers offered features like this, it would be a good bonus, but I'm not sure I would mandate it as a requirement or recommendation for RPC nodes, as it fits nicely as an extension.

@kumavis
Copy link
Member

kumavis commented May 12, 2016

middleware server in front of the RPC

@wighawag have you tried this at least as a proof of concept? I think it might be appealing for a number of users

@wighawag
Copy link
Contributor Author

Thanks for the feedback.

@FlySwatter It definitely works without CORS. The idea is that the authorization.html will be served by the node on the same rpc domain/port. I have just tested it. I had to fix a recent change as it was accessing some member of the opener window but it works again now. If you want to test it I have also created a Pull request for geth : ethereum/go-ethereum#2534

The main point for me was to have it as part of a node so that user do not require to trust anything else, hence the CORS being not required being very important. That's why it would need to be part of the RPC specification, hence the proposal here.

Dapp would then be able to run on the web directly in user's everyday browser. This is for me a huge improvement to the ethereum user experience. A wallet (like mist) could even be run directly from a website without trust required.

While we could argue that a dedicated wallet/dapp browser would serve the same role, I would argue that while the same role is fulfilled, it require the use of yet another software. Being able to use the user's everyday browser has a clear advantage in term of user experience. It also open access to all kind of machine that do not necessarly support a dedicated app but have a browser (they would still need a node though).

In that new light, what do you think?

@kumavis my dapp I am currently working on is using it. If this does not make it in the spec and the node before I launch, I still plan to use this html page but will require the user to enable CORS for the domain/port on which the html page is served. This is of course not ideal but I could alternatively offer the user a python or node script that they can download that serve the html page on a particular port. This way, trust is minimized as they can inspect the script and the page. They would still need to enable CORS but for localhost: only.

@danfinlay
Copy link
Contributor

Please forgive me @wighawag , I had initially skimmed and not understood your clever use of a localhost iframe and postMessage. (I am partly assuming the iframe points to the localhost server, it is not made very explicit in the post, but I'm pretty sure I now understand that's how this works).

This does look reasonably secure, and I now think it does actually require an EIP because it requires both the support of RPC nodes and the encouragement of Dapp developers to integrate this new iFrame protocol.

A couple extra notes:

  • This seems to require ethereum RPCs to always run on a fixed port. It may be unlikely that users run other things on port 8545, but it seems a little strange to require it. Can you imagine a way to make the protocol more port-flexible, without requiring users to explicitly declare the port to each new dapp?
  • You suggest eth_sign would be insecure with this interface. I don't think eth_sign is inherently less secure in this interface than in any other context. What more do you think should be done?

Ultimately, it's actually pretty great how simply this gets web-dapp compatibility into normal browsers. It doesn't answer larger questions about convenient account/identity management, but makes for a very efficient minimum viable ethereum browser.

It wouldn't take much to add it to an RPC node, so most of the complexity is adding it to the list of things that Dapp developers should try in order to connect to a user's blockchain. I suppose we could roll all available strategies into a single recommended web3-finder module, and just try to promote its use in the community as a way to simplify developer experience.

@wighawag
Copy link
Contributor Author

@FlySwatter thanks for taking the time to read it again. I am glad you see the benefits.

I am not sure I follow your question regarding fixed port. The html page needs to be served on the same domain and port on which the node is listening on (for its rpc api) for it to not require CORS. But the node itself (and thus its html page) do not need to listen on localhost:8545. It does not even need to be localhost. It can be anywhere like the current nodes can. The dapp will just need to point the iframe and popup to the same url as the rpc url. I have such node (a private net) running here : http://146.185.139.84:8545 (future reader : the availability of this server is not guaranteed)
you can access the html page here : http://146.185.139.84:8545/authorization.html . Let me know if it answers your question. See also below what a dapp developer needs to do to use such authorization mechanism.

The reasoning behind not allowing eth_sign was that it would be hard to display the content of the transaction in any meaningful way. You are right thought that it should be the same in any other context. I assumed that what is given to eth_sign is just a series of byte. But if there is way to extract information (the value, gas, gasPrice, sender and receiver) from the bytes in a generic way, then yes, eth_sign would be possible. Do you do it with Metamask, if so how (so I can put it in there as well)?

On that note, even in the case of eth_sendTransaction the data sent along the transaction are bytes and its meaning is dapp specific. There is no way to display meaningful information in a generic way but this problem is also present in other wallets and does not affect the ether balance. It could on the other hand affects valuable token balance that reside in other contracts states but since contract code is public such potential abuse would be potentially visible. Again not an issue with this authorization method itself as this is present in other context too.

Indeed, adding it to an RPC node is trivial. all the complexity reside in the html page itself. This also means that any fixes can be shared easily.
An example for geth is here : ethereum/go-ethereum#2534

Regarding dapp developer, I already made a web3-html-provider here: https://github.com/wighawag/web3-html-provider/blob/master/html-provider.js. I use it to test the authorization mechanism and this actually helped refine how the html page works internally, especially in regard to popup behaviors.

The only thing the dapp developer need to do is

var nodeUrl = "localhost:8545"; //or whatever the node is listening on
web3.setProvider(new HtmlProvider(nodeUrl)); 

instead of

var nodeUrl = "localhost:8545"; //or whatever the node is listening on
web3.setProvider(new web3.providers.HttpProvider(nodeUrl)); 

Note that HtmlProvider do not allow sync calls (as postMessage is async and confirmation of the user too obviously).

Also, because of the usual browser's popup blocker behavior, any eth_senTransaction call should be triggered in a click event handler so that the popup is not blocked.

Thanks again for the feedback

@tomusdrw
Copy link

tomusdrw commented May 18, 2016

  1. Dapp developers are already adviced to check if global web3 exists:
    https://github.com/ethereum/wiki/wiki/JavaScript-API#adding-web3
    Server could also host web3.js file that could be included by dapp developer in <head> - this would be less hassle then creating HtmlProvider on their own.
  2. If this gets traction it makes all sync calls in web3 obsolete - refactoring of web3 library should follow this by removing the sync calls (we can still have a special version that would be used in "console" environment, when sync calls are very convenient)
  3. I would consider serving the page over https (with self signed certificate) to mitigate mitm and avoid sending my plain-text key password over http.
  4. Should use eth: add new RPC method (personal.) SignAndSendTransaction go-ethereum#2564 instead of unlocking the account (imho personal_unlockAccount should be removed from all clients asap)

@wighawag
Copy link
Contributor Author

@tomusdrw thanks for the feedback.
I agree with all of it. Did not know about ethereum/go-ethereum#2564 and would update this when ready. This is a lot better.

@adridadou
Copy link

Hi everyone, I still think it is a bad practice to let people create transactions directly from their browser.

The idea is to have some kind of control over the context in which you are susceptible of creating a transaction.

Doing anything on the blockchain is very sensitive. If you do something wrong or you get fooled, you may lose everything you have on your account. More concretely, here are my two points against something like that:

  1. Keep the Ethereum context. If you are in Mist, you are alert. If a funny looking popup comes up, you will read it carefully and most probably won't enter your password if you don't absolutely trust it.
    If you are browsing somewhere and suddenly a popup comes, you may think it makes sense, you may not think too much and simply click ok. Especially if you have unlocked your account it can happen very fast.
  2. Mist integration for transaction signing is nice and consistent. You get a clear popup that looks always the same and you always need to enter your password. I think that having an actual application to prevent writing your password over and over again makes more sense than having the possibility to do it from the browser where you are just an URL away from losing all your ETH.

@wighawag
Copy link
Contributor Author

Hi @adridadou thanks for the feedback.I personally do not think these are clear cut issues. Here are my replies:

  1. Until we have mist adopted I think it is an assumption to state that user will be "more" alert using mist than in their everyday browser.
    I do not follow what you mean by "funny looking". If that EIP is approved we can have a standard looking popup. I do not think user will click OK without thinking on something that state will transfer their ether. We could add a confirmation too if that is a risk. Also you might have misunderstood the proposal. The UI is provided by the node. If a funny looking popup is shown this means it is being served by something else, hence it would not have the permission to do the transaction. it might be able to trump the user to enter the password though. But this is something popup can do in any context.
  2. With that proposal we can also get a nice and consistent looking popup. We can also enforce the use of password if we decide to. On that note, mist is unlikely to be the only dapp browser out there and every talk of standard UI need to consider that there might be a multitude of standard later. If ever we can enforce a standard UI, we could do it as part of that proposal.

In other word I do not see anything that make mist more trust worthy than a popup provided by the node.

I think we need to take the view of the average user and dapp developer here as this is in that context that this proposal shines:

  1. The ability for user to use their everyday browser is of great benefit from a usability standpoint :
  • no need to install and trust yet another software.
  • provide user with their everyday tools (extensions, configurations, bookmarks... etc..)
  1. For dapp developer it means that they can build their website for the web and can provide links without explaining the need for an extra software (except the node itself). navigation can also happen freely among hyperlinks.
  2. ability for any web browser enabled devices that have access to a node to use dapps. It means user of devices where mist is not released can still use dapps.
  3. allow non html5 (native) app to provide their user with a way to send transaction in a secure way (without requiring trust from the users)

I am looking forward to the mist browser release but think having the option to allow user to interact with dapps with their everyday browser is something we should thrive to achieve.

@adridadou
Copy link

adridadou commented May 24, 2016

Hi,
First thank you for the precisions on the PR, it's true I haven't fully understood it.
I'll try to explain how I see a solution that, I think, is secure enough.

Any browser that wants access needs to ask to enable the capability. A whitelist is maintained per session. This way, each user know that he enters a website where Ethereum is used and it prevents phishing attacks.

Then for each transaction, you need to see:

  1. The domain the transaction comes from
  2. The destination address
  3. The function name if available
  4. The user has to enter his password, everytime

When I say that it has to be in Mist this is not Mist necessarily I'm talking more about having a special place for it. It's true that when you work on a dApp you tend to think of it as unlocking a user but it is more like leaving your online bank account session open.

In any dApp manager / store, you never browse there. You usually open a specific application. Then, Mist has this logic where you have to explicitly link the dApp with an account. It takes the one account if you have only one or you can chose which one to use.

So again I'm taking Mist as an example because it is the only one available today but this could be any dApp manager. So in the Mist browser, you know that you have to explicitly say for each dApp, I want to use my account on it so you are sure you won't have someone suddenly trying to make you send tx.

And about phishing, imagine someone uses the system with your EIP. like everybody, he has around 20 tabs open. Now he is playing a dApp game that create a fair amount of transactions but an attacker has created a hidden page running in the background from one of the other tabs and the phisher hopes that if he creates tx in the middle of your game you won't notice it is for something else and you will confirm it. You are in the middle of your game, you have loads of tx to confirm, you don't pay attention and then you have sent ETH to your attacker.

Regarding your points:

  1. This is not true. You need to install a node. And for an end user, I think it is easier to handle a UI than having a node running in the background. Also, the web is a jungle. You don't want ppl to play with their valuable ETH from there. So I would trust less the system if it worked directly from chrome / ie etc ...
  2. Again, I think it is easier for an end user to use a UI to go to your website than running a daemon.
  3. Can you give me an example of a device where you can install a node but not Mist ?
  4. That is possible already in different languages. In go there is a native integration available, I've written a java lib to do the same. And yes there you don't need RPC so no need for any of this. And the native app is also a very good example. We need to be very careful with that. Imagine a virus listening to the communication with geth and try to copy legitimate tx but with another account as a destination?

Regards

@wighawag
Copy link
Contributor Author

@adridadou thanks for your comments,

I like the idea of the dapp wesbite domain asking for permission before hand, this should be easily achievable. A popup would then say something like "the domain <example.com> is attempting to connect to your ethereum node at <url>, do you want to allow it. For transaction it will ask you for permission...".

regarding the info to display:

  1. The domain the transaction comes from : good point, easy to add
  2. The destination address : already there using the blockie image but we can add the text version too
  3. The function name if available : I guess it should be available somehow but this would require sending the abi and not sure how we would ensure it is the right one. does mist do it, if so how?
  4. The user has to enter his password, everytime : Can be done (will use this: eth: add new RPC method (personal.) SignAndSendTransaction go-ethereum#2564 when ready)

regarding my points few clarifications:

  1. Obviously we need the node, but in case of mist this is the node + mist. You can argue that the node is bundled with mist and I guess you have a point :) On the other hand the ability to use your everyday browser is still a very big plus for the user.
  2. The node can be a gui too, my point was that for the dapp developer there is no need to ask the user to launch its website in another software. just navigate as usual, From the user point of view, this a lot better too. there is no need to switch software in order to use the website. This remove friction for ethereum.
  3. I do not have an example right now but this might happen when ethereum become widespread and node become a default software. You can also imagine having the node running on another machine. And the device you access the website might be a proprietary device that for one reason or another do not support mist. I agree that this is speculation and this point can be ignored for now.
  4. If a dapp use language binding it will have to unlock account and thus can do phising or can steal your ether easily. By making sure native dapps need to use the proposal, the security is handled the same. Regarding your virus, you cannot just copy a tx and change the destination account, you would have to resign it. In any case this is an issue present in other context too. Also as @tomusdrw suggested the communication should be done via https to avoid passing the password in clear.

What do you think now about the proposal?

@adridadou
Copy link

Hi,
So I'm glad you like the hostname whitelist. I think it is an important feature.

I am still not convinced about using your own browser for that. My main issue is that I think this is healthy to separate them.

So to come again to the points:

  1. Personally I see using your browser as a hazard more than a plus, but I think this is subjective.
  2. As I said before, I think this is healthy to ask for that. I like to chose when and if a website can see that I have an Ethereum account, what my account is and then how much Ether I have.
  3. I really doubt this is a valid point. There is no reason to think that any device able to run go-ethereum won't have a proper UI app like Mist or something specific to it.
  4. In the case of the virus, I am talking about recreating a transaction. The idea is to hope you don't read well what is going on and you think it was a glitch and you resign the transaction. When you are doing something and you are expecting a pop up to come, you are more likely to accept a second one without checking all the details. It won't work all the time but you need only once. How many ppl clicked on the wrong file in an email because they thought there was nothing to fear? Usually because of the sender's identity.

I think that the main issue today is that Mist browser is not released with Mist wallet and therefore there is no easy way to tell to someone "come to my website with ... and play / work / do your thing". And I've been there and when I was working on my dApp I had the same idea too but then after building Mist browser I liked the security measures put in place and I think we need a controlled env where people are more aware of what they do. Again this is my subjective view, but as soon as you play with something valuable I think we need the security not only technical but social too. Especially non tech savvy ppl get easily manipulated when a message comes from a computer. I could even imagine ppl forging a false ethereum popup to steal your password and because they can see your account they can send transactions on your behalf at any time.

Very interested to see the outcome of this discussion. Have a nice day

@kumavis
Copy link
Member

kumavis commented May 31, 2016

@Arachnid
Copy link
Contributor

"Authorization fatigue" is a real problem, and @adridadou is right that it can lead to users authorizing things they didn't intend to. There are ways around this, however, by expanding the scope of authorizations: a DApp should be able to ask for permission to, for instance "Send transactions to address x with fees totalling at most y ether"; that authorization would then be good until they exhaust the allowed value.

I think concerns about not allowing this in a browser are ill-founded. If we want DApps to become a part of everyday life, they have to interact with the web, not be their own little walled garden.

@Arachnid
Copy link
Contributor

Arachnid commented Feb 21, 2017

EIP editor here: We've concluded that for ERCs like this, the best path to acceptance is to accept them when they have at least one implementation.

Please tag with editor-needs-to-review when you feel it's ready to go.

Also, please enable allow edits from maintainers

@wighawag
Copy link
Contributor Author

Does the implementations need to be complete or can it just be functional ?
I used to have an implementation as a pull request in geth (ethereum/go-ethereum#2534). It is now out of date but I could update it.

@Arachnid
Copy link
Contributor

Change of plans: We'll be accepting EIPs in and giving them numbers under 'draft' status. If you'd like to have this merged, please:

  • Assign this EIP number 107 and rename accordingly.
  • Add 'Category: Interface' in the preamble

EIPS/eip-107.md Outdated
@@ -0,0 +1,614 @@
<pre>
EIP: draft
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please set this to 107.

@Arachnid Arachnid merged commit 58a108b into ethereum:master Apr 19, 2017
@axic
Copy link
Member

axic commented May 23, 2019

@wighawag this EIP doesn't have a copyright statement. Can you please add one? EIP-1 suggests CC0 - see the eip-x.md template.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants