From 7f6be2fc41be3c33167702a0b1f858aab046023a Mon Sep 17 00:00:00 2001 From: wighawag Date: Sat, 7 May 2016 06:30:33 +0100 Subject: [PATCH 01/16] draft-dapp-html-authorization --- EIPS/draft-dapp-html-authorization.md | 34 +++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 EIPS/draft-dapp-html-authorization.md diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md new file mode 100644 index 00000000..0cfa9cb5 --- /dev/null +++ b/EIPS/draft-dapp-html-authorization.md @@ -0,0 +1,34 @@ +
+  EIP: draft
+  Title: sendTransaction authorization via html
+  Author: Ronan Sandford 
+  Created: 2016-06-05
+  Status: Draft
+  Type: Standard
+
+ +Abstract +======== +This draft EIP describes the details of an authorization method provided by rpc enabled ethereum node allowing regular website to to send transaction (via "eth_sendTransaction") without the need to enable CORS for the website domain but instead ask the user permission. This would allow user to safely unlock their account while interacting with web based app running in their everyday web browser. + +Motivation +========== +Currently, if a user navigate to a dapp running on a website using his/her everyday browser, the dapp has either full access to "eth_sendTransaction" and "eth_sign" (if the user launched its node with CORS enabled for the website domain) or (more likely) none at all. In other word the user is forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapp to rely on the use of workarround like: +- if the transaction is plain ether transfer the user is asked to enter it in the mist wallet +- For more complex case, the user is asked to enter the transaction manually via the node command line interface. + +Specification +============= +The dapp instead of connecting directly to the node, will instead communicate via 2 channels (a embeded invisible iframe for call that do not require an unlocked keys (most rpc calls) and a window for call to "eth_sendTransaction". call to "eth_sign" are not authorized since there is no way to display to the user the meaningfull content of the transaction in a safe way. +The invisible iframe allow teh dapp to continue making rpc call to the node without any CORS enabled. +The window on the other hand provide the dapp the only way to make a call to "eth_sendTransaction" by asking the user to confirm or cancel the transaction via a html dialog. + + +Rationale +========= + +Backward Compatibility +================= + +Implementations +=============== From 22a8af4b2b881058ffa081af67daaf4fdf79b5c3 Mon Sep 17 00:00:00 2001 From: wighawag Date: Sat, 7 May 2016 08:00:34 +0100 Subject: [PATCH 02/16] first draft --- EIPS/draft-dapp-html-authorization.md | 30 +++++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index 0cfa9cb5..07a7f3cc 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -1,6 +1,6 @@
   EIP: draft
-  Title: sendTransaction authorization via html
+  Title: safe "eth_sendTransaction" authorization via html popup
   Author: Ronan Sandford 
   Created: 2016-06-05
   Status: Draft
@@ -9,26 +9,38 @@
 
 Abstract
 ========
-This draft EIP describes the details of an authorization method provided by rpc enabled ethereum node allowing regular website to to send transaction (via "eth_sendTransaction") without the need to enable CORS for the website domain but instead ask the user permission. This would allow user to safely unlock their account while interacting with web based app running in their everyday web browser.
+This draft EIP describes the details of an authorization method provided by rpc enabled ethereum nodes allowing regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain. This is done by asking the user permission via an html popup served by the node itself. This allow users to to safely unlock their account while interacting with web based dapps running in their everyday web browser.
 
 Motivation
 ==========
-Currently, if a user navigate to a dapp running on a website using his/her everyday browser, the dapp has either full access to "eth_sendTransaction" and "eth_sign" (if the user launched its node with CORS enabled for the website domain) or (more likely) none at all. In other word the user is forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapp to rely on the use of workarround like:
-- if the transaction is plain ether transfer the user is asked to enter it in the mist wallet 
+Currently, if a user navigate to a dapp running on a website using her/his everyday browser, the dapp will have by default no access to the rpc node for security reason. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user do so, the dapp will be able to send transaction from any unlocked account without the need for any user consent. In other word not only the user need to change its node default setting but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapps to rely on the use of workarround like:
+- if the transaction is a plain ether transfer the user is asked to enter it in a dedicated trusted wallet like "Mist"
 - For more complex case, the user is asked to enter the transaction manually via the node command line interface.
+This proposal aims to provide a safe and user friendly alternative.
 
 Specification
 =============
-The dapp instead of connecting directly to the node, will instead communicate via 2 channels (a embeded invisible iframe for call that do not require an unlocked keys (most rpc calls) and a window for call to "eth_sendTransaction". call to "eth_sign" are not authorized since there is no way to display to the user the meaningfull content of the transaction in a safe way.
-The invisible iframe allow teh dapp to continue making rpc call to the node without any CORS enabled.
-The window on the other hand provide the dapp the only way to make a call to "eth_sendTransaction" by asking the user to confirm or cancel the transaction via a html dialog.
+In order for the mechanism to work, the node need to serve a static html file via http at the url /authorization 
+This file will then be used by the dapp in 2 different modes (invisible iframe and popup window).
+The invisible iframe will be embeded in the dapp to allow the dapp to send its rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port.
+In iframe node the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapp for embedding the visible iframe and tricking the user into clicking the confirm button.
+If the dapp requires to make an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url.
+In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (not  ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request.
 
 
 Rationale
 =========
+The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. 
+The current design, instead has a very simple implementation (static html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies.
+The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allow the dapp to execute read only calls without the need for user input and the window ensure the user approve before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser "window.confirm" dialog, this would have prevented the use of a more elegant confirmation popup that the current design allow.
 
-Backward Compatibility
-=================
 
 Implementations
 ===============
+In order to implement this design, the following html file need to be served at the url /authorization
+That's it
+
+
+```
+
+```
\ No newline at end of file

From 30fa6b371e49e73893dd53758ee4668d791713e9 Mon Sep 17 00:00:00 2001
From: wighawag 
Date: Sun, 8 May 2016 18:21:04 +0100
Subject: [PATCH 03/16] link image

---
 EIPS/draft-dapp-html-authorization.md         | 411 +++++++++++++++++-
 .../authorization.png                         | Bin 0 -> 20405 bytes
 2 files changed, 404 insertions(+), 7 deletions(-)
 create mode 100644 EIPS/draft-dapp-html-authorization/authorization.png

diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md
index 07a7f3cc..67abb784 100644
--- a/EIPS/draft-dapp-html-authorization.md
+++ b/EIPS/draft-dapp-html-authorization.md
@@ -9,7 +9,7 @@
 
 Abstract
 ========
-This draft EIP describes the details of an authorization method provided by rpc enabled ethereum nodes allowing regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain. This is done by asking the user permission via an html popup served by the node itself. This allow users to to safely unlock their account while interacting with web based dapps running in their everyday web browser.
+This draft EIP describes the details of an authorization method provided by rpc enabled ethereum nodes allowing regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain. This is done by asking the user permission via an html popup served by the node itself. This allow users to to safely unlock their account while interacting with web based dapps running in their everyday web browser. The html page also allow the user to enter their password when the account is unlocked and the node allowed "personal" api via rpc.
 
 Motivation
 ==========
@@ -17,22 +17,23 @@ Currently, if a user navigate to a dapp running on a website using her/his every
 - if the transaction is a plain ether transfer the user is asked to enter it in a dedicated trusted wallet like "Mist"
 - For more complex case, the user is asked to enter the transaction manually via the node command line interface.
 This proposal aims to provide a safe and user friendly alternative.
+
 
 Specification
 =============
-In order for the mechanism to work, the node need to serve a static html file via http at the url /authorization 
+In order for the mechanism to work, the node need to serve an html file via http at the url /authorization.html
 This file will then be used by the dapp in 2 different modes (invisible iframe and popup window).
-The invisible iframe will be embeded in the dapp to allow the dapp to send its rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port.
+The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. The iframe first message is a message containing the string "ready" to let the parent know that it know accept messages.
 In iframe node the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapp for embedding the visible iframe and tricking the user into clicking the confirm button.
 If the dapp requires to make an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url.
-In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (not  ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request.
-
+In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (not  ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. Similarly to the iframemode, the window first message is a message containing the string "ready" to let the opener know that it know accept messages.
+The html page also check for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time.
 
 Rationale
 =========
 The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. 
 The current design, instead has a very simple implementation (static html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies.
-The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allow the dapp to execute read only calls without the need for user input and the window ensure the user approve before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser "window.confirm" dialog, this would have prevented the use of a more elegant confirmation popup that the current design allow.
+The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allow the dapp to execute read only calls without the need for user input and the window ensure the user approve before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser ```window.confirm``` dialog, this would have prevented the use of a more elegant confirmation popup that the current design allow. It also happen to be that the ```window.confirm``` is not safe in some browser as it give focus to the accept option and can be triggered automatically (https://bugs.chromium.org/p/chromium/issues/detail?id=260653).
 
 
 Implementations
@@ -42,5 +43,401 @@ That's it
 
 
 ```
-
+
+
+    
+        Ethereum Authorization
+    
+    
+    
+    
+    
+    
+
+        
+
+

Please wait...

+
+ +
+
+

+

+ + +
+ + + + + + ``` \ No newline at end of file diff --git a/EIPS/draft-dapp-html-authorization/authorization.png b/EIPS/draft-dapp-html-authorization/authorization.png new file mode 100644 index 0000000000000000000000000000000000000000..b7dc9ae09806c6e93aed38317169b0c12452c1b0 GIT binary patch literal 20405 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 literal 0 HcmV?d00001 From 50ce9f45e4eacd6f45e9ad89bf10a98c2b5d4952 Mon Sep 17 00:00:00 2001 From: wighawag Date: Sun, 8 May 2016 18:26:03 +0100 Subject: [PATCH 04/16] add more images --- EIPS/draft-dapp-html-authorization.md | 6 ++++++ .../authorization-locked.png | Bin 0 -> 23224 bytes .../authorization-password.png | Bin 0 -> 22099 bytes 3 files changed, 6 insertions(+) create mode 100644 EIPS/draft-dapp-html-authorization/authorization-locked.png create mode 100644 EIPS/draft-dapp-html-authorization/authorization-password.png diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index 67abb784..479c4338 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -16,9 +16,15 @@ Motivation Currently, if a user navigate to a dapp running on a website using her/his everyday browser, the dapp will have by default no access to the rpc node for security reason. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user do so, the dapp will be able to send transaction from any unlocked account without the need for any user consent. In other word not only the user need to change its node default setting but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapps to rely on the use of workarround like: - if the transaction is a plain ether transfer the user is asked to enter it in a dedicated trusted wallet like "Mist" - For more complex case, the user is asked to enter the transaction manually via the node command line interface. + + This proposal aims to provide a safe and user friendly alternative. + + + + Specification ============= In order for the mechanism to work, the node need to serve an html file via http at the url /authorization.html diff --git a/EIPS/draft-dapp-html-authorization/authorization-locked.png b/EIPS/draft-dapp-html-authorization/authorization-locked.png new file mode 100644 index 0000000000000000000000000000000000000000..4f881bcafe0e75eec48992ab251e811653367cb3 GIT binary patch literal 23224 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 Date: Sun, 8 May 2016 18:28:06 +0100 Subject: [PATCH 05/16] title to images --- EIPS/draft-dapp-html-authorization.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index 479c4338..1b92bd43 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -18,12 +18,20 @@ Currently, if a user navigate to a dapp running on a website using her/his every - For more complex case, the user is asked to enter the transaction manually via the node command line interface. -This proposal aims to provide a safe and user friendly alternative. +This proposal aims to provide a safe and user friendly alternative: + +Account unlocked : +----------------- +Account locked and no "personal" api exposed via rpc: +----------------- + + +Account locked but node exposing the "personal" api via rpc : +----------------- - Specification ============= From d7bdc8c10a86026514ab0a7cba40d454ecec2f73 Mon Sep 17 00:00:00 2001 From: wighawag Date: Sun, 8 May 2016 23:25:30 +0100 Subject: [PATCH 06/16] progress --- EIPS/draft-dapp-html-authorization.md | 30 ++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index 1b92bd43..f0809f0c 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -9,50 +9,66 @@ Abstract ======== -This draft EIP describes the details of an authorization method provided by rpc enabled ethereum nodes allowing regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain. This is done by asking the user permission via an html popup served by the node itself. This allow users to to safely unlock their account while interacting with web based dapps running in their everyday web browser. The html page also allow the user to enter their password when the account is unlocked and the node allowed "personal" api via rpc. +This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain but instead with the required consent from the users. + +For every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allow users to safely interact with dapp running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. Motivation ========== -Currently, if a user navigate to a dapp running on a website using her/his everyday browser, the dapp will have by default no access to the rpc node for security reason. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user do so, the dapp will be able to send transaction from any unlocked account without the need for any user consent. In other word not only the user need to change its node default setting but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapps to rely on the use of workarround like: +Currently, if a user navigate to a dapp running on a website using her/his everyday browser, the dapp will have by default no access to the rpc api for security reason. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user do so, the dapp will be able to send transaction from any unlocked account without the need for any user consent. In other word not only the user need to change its node default setting but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapps to rely on the use of workarround like: - if the transaction is a plain ether transfer the user is asked to enter it in a dedicated trusted wallet like "Mist" - For more complex case, the user is asked to enter the transaction manually via the node command line interface. This proposal aims to provide a safe and user friendly alternative: +Here are some screenshot of the provided implementation of that html popup: + Account unlocked : ----------------- +When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make : + Account locked and no "personal" api exposed via rpc: ----------------- +When the account is locked and the node do not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this require the user to know how to unlock an account: + Account locked but node exposing the "personal" api via rpc : ----------------- +A better option is to ask the user the password but this is only possible if the node allow access to the "personal" api via rpc. In such case the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: + Specification ============= -In order for the mechanism to work, the node need to serve an html file via http at the url /authorization.html +In order for the mechanism to work, the node need to serve an html file via http at the url \/authorization.html + This file will then be used by the dapp in 2 different modes (invisible iframe and popup window). -The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. The iframe first message is a message containing the string "ready" to let the parent know that it know accept messages. + +The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. The iframe first message is a message containing the string "ready" to let the parent know that it now accepts messages. + In iframe node the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapp for embedding the visible iframe and tricking the user into clicking the confirm button. If the dapp requires to make an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. -In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (not ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. Similarly to the iframemode, the window first message is a message containing the string "ready" to let the opener know that it know accept messages. + +In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. Similarly to the iframe mode, the window first message is a message containing the string "ready" to let the opener know that it now accepts messages. + The html page also check for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time. Rationale ========= The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. -The current design, instead has a very simple implementation (static html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies. +The current design, instead has a very simple implementation (self contained html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies. + The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allow the dapp to execute read only calls without the need for user input and the window ensure the user approve before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser ```window.confirm``` dialog, this would have prevented the use of a more elegant confirmation popup that the current design allow. It also happen to be that the ```window.confirm``` is not safe in some browser as it give focus to the accept option and can be triggered automatically (https://bugs.chromium.org/p/chromium/issues/detail?id=260653). Implementations =============== -In order to implement this design, the following html file need to be served at the url /authorization +In order to implement this design, the following html file need to be served at the url \/authorization.html That's it From 15e4c31d443363ad1d514689f2da59a816c307bd Mon Sep 17 00:00:00 2001 From: wighawag Date: Mon, 9 May 2016 16:41:46 +0100 Subject: [PATCH 07/16] improvements --- EIPS/draft-dapp-html-authorization.md | 801 +++++++++++++------------- 1 file changed, 415 insertions(+), 386 deletions(-) diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index f0809f0c..f34c59dd 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -9,9 +9,9 @@ Abstract ======== -This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS for the website's domain but instead with the required consent from the users. +This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS. Instead, user would be asked to confirm the transaction via an html popup. -For every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allow users to safely interact with dapp running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. +Every read only rpc calls the dapp want to perform are redirected to an invisible iframe from the node's domain and for every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allow the dapp to connect to the node's rpc api without being granted any kind of privileges. This allow users to safely interact with dapp running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. Motivation ========== @@ -20,7 +20,7 @@ Currently, if a user navigate to a dapp running on a website using her/his every - For more complex case, the user is asked to enter the transaction manually via the node command line interface. -This proposal aims to provide a safe and user friendly alternative: +This proposal aims to provide a safe and user friendly alternative. Here are some screenshot of the provided implementation of that html popup: @@ -49,15 +49,46 @@ In order for the mechanism to work, the node need to serve an html file via http This file will then be used by the dapp in 2 different modes (invisible iframe and popup window). -The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. The iframe first message is a message containing the string "ready" to let the parent know that it now accepts messages. +The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. In iframe node the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapp for embedding the visible iframe and tricking the user into clicking the confirm button. If the dapp requires to make an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. -In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. Similarly to the iframe mode, the window first message is a message containing the string "ready" to let the opener know that it now accepts messages. +In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. The html page also check for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time. +In both iframe mode and window mode, the communication with the dapp is achieved using ```window.postMessage```. +The fist message the iframe/window send is a message containing the string "ready" to let the dapp know that it now accepts messages. Then the dapp can start performing rpc call by sending message using the following object : +``` +{ + id:, //so responses can be match as there is no guarantee of the order of the response + payload: //this is the exact object that usually send to the node +} +``` + +For ```eth_sendTransaction``` the "gas", "gasPrice" and "from" field need to be set in the rpc parameter so that the window can display the correct value. If not all of these are passed in, the window will return an error. + +Upon receiving such message, the iframe will perform the actual rpc call to the node but only if such a call is a read only call (not requiring an unlocked key). If it is not it will return a error. The window on the other will also accept ```eth_sendTransaction``` calls but will display a dialog so the user can accept or cancel the request. + +In all the cases, the iframe/window will send a message back to the dapp using the following object: +``` +{ + id:, + result:, + error: +} +``` + +the error object cannot be a javascript Error object due to postMessage limitation. Instead it is +``` +{ + message:, + type: //type="cancel" means the user cancel the transaction +} +``` + + Rationale ========= The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. @@ -68,406 +99,404 @@ The use of iframe/ window was required to have both security and user friendline Implementations =============== -In order to implement this design, the following html file need to be served at the url \/authorization.html +In order to implement this design, the following html file or an equivalent one need to be served at the url \/authorization.html + That's it ``` - - Ethereum Authorization - + + Ethereum Authorization + + + + + + + +
+
+

Please wait...

+
+ +
+
+

+

+ + +
+ + + + var pleaseWait = document.getElementById("pleasewait"); + var form = document.getElementById("form"); + var cancelButton = document.getElementById("cancel-button"); + var confirmButton = document.getElementById("confirm-button"); + var message = document.getElementById("message"); + var password = document.getElementById("password"); + var passwordField = document.getElementById("passwordField"); + var modalDialog = document.getElementById("modal-dialog"); + var modalDialogButton = document.getElementById("modal-dialog-button"); + var modalDialogTitle = document.getElementById("modal-dialog-title"); + var modalDialogMessage = document.getElementById("modal-dialog-message"); - + }; + + try { + request.send(JSON.stringify(payload)); + } catch(e) { + callback({message:'CONNECTION ERROR: Couldn\'t connect to node '+ url +'.',type:"noConnection"}); + } + } - - -
-
-

Please wait...

-
- -
-
-

-

- - -
+ function addBlocky(message, address){ + var icon = blockies.create({ + seed: address, + size: 8, + scale: 6 + }); + message.appendChild(icon); + } - - - - + }else{ + sendAsync(data.url,data.payload,function(error,result){ + sourceWindow.postMessage({id:data.id,result:result,error:error},sourceWindow.location.href); + }); + } + } + + + window.addEventListener("message", receiveMessage); + if(source){ + source.postMessage("ready",source.location.href); + } + + + ``` \ No newline at end of file From f3cb9f599e71f4232e3af7f4147e6d3bdc18aaec Mon Sep 17 00:00:00 2001 From: wighawag Date: Tue, 10 May 2016 18:39:24 +0100 Subject: [PATCH 08/16] improvements to html implementation --- EIPS/draft-dapp-html-authorization.md | 91 +++++++++++++++++++-------- 1 file changed, 65 insertions(+), 26 deletions(-) diff --git a/EIPS/draft-dapp-html-authorization.md b/EIPS/draft-dapp-html-authorization.md index f0809f0c..025fd318 100644 --- a/EIPS/draft-dapp-html-authorization.md +++ b/EIPS/draft-dapp-html-authorization.md @@ -198,13 +198,13 @@ That's it

Please wait...

-
+

- - -
+ + + From ed674d282bade2636790ed504edd8f71af18d5b0 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 12 May 2016 01:34:19 -0700 Subject: [PATCH 13/16] Corrected some grammar. --- EIPS/eip-XXX.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/EIPS/eip-XXX.md b/EIPS/eip-XXX.md index ba13a3ca..db829030 100644 --- a/EIPS/eip-XXX.md +++ b/EIPS/eip-XXX.md @@ -11,55 +11,55 @@ Abstract ======== This draft EIP describes the details of an authorization method that if provided by rpc enabled ethereum nodes would allow regular websites to send transactions (via ```eth_sendTransaction```) without the need to enable CORS. Instead, user would be asked to confirm the transaction via an html popup. -Every read only rpc calls the dapp want to perform are redirected to an invisible iframe from the node's domain and for every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allow the dapp to connect to the node's rpc api without being granted any kind of privileges. This allow users to safely interact with dapp running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. +Every read only rpc call the dapp wants to perform is redirected to an invisible iframe from the node's domain and for every transaction that the dapp wish to execute, an html popup is presented to the user to allow him/her to cancel or confirm the transaction. This allows the dapp to connect to the node's rpc api without being granted any kind of privileges. This allows users to safely interact with dapps running in their everyday web browser while their accounts are unlocked. In case the account is not unlocked, and the node has allowed the "personal" api via rpc,the html page also allow the user to enter their password to unlock the account for the scope of the transaction. Motivation ========== -Currently, if a user navigate to a dapp running on a website using her/his everyday browser, the dapp will have by default no access to the rpc api for security reason. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user do so, the dapp will be able to send transaction from any unlocked account without the need for any user consent. In other word not only the user need to change its node default setting but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and force existing dapps to rely on the use of workarround like: -- if the transaction is a plain ether transfer the user is asked to enter it in a dedicated trusted wallet like "Mist" +Currently, if a user navigates to a dapp running on a website using her/his everyday browser, the dapp will by default have no access to the rpc api for security reasons. The user will have to enable CORS for the website's domain in order for the dapp to work. Unfortunately if the user does so, the dapp will be able to send transactions from any unlocked account without the need for any user consent. In other words, not only does the user need to change the node's default setting, but the user is also forced to trust the dapp in order to use it. This is of course not acceptable and forces existing dapps to rely on the use of workarrounds like: +- if the transaction is a plain ether transfer, the user is asked to enter it in a dedicated trusted wallet like "Mist" - For more complex case, the user is asked to enter the transaction manually via the node command line interface. This proposal aims to provide a safe and user friendly alternative. -Here are some screenshot of the provided implementation of that html popup: +Here are some screenshots of the provided implementation of that html popup: Account unlocked : ----------------- -When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make : +When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make: Account locked and no "personal" api exposed via rpc: ----------------- -When the account is locked and the node do not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this require the user to know how to unlock an account: +When the account is locked, and the node does not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this requires the user to know how to unlock an account: Account locked but node exposing the "personal" api via rpc : ----------------- -A better option is to ask the user the password but this is only possible if the node allow access to the "personal" api via rpc. In such case the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: +A better option is to ask the user for their password, but this is only possible if the node allows access to the "personal" api via rpc. In such case, the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: Specification ============= -In order for the mechanism to work, the node need to serve an html file via http at the url \/authorization.html +In order for the mechanism to work, the node needs to serve an html file via http at the url \/authorization.html This file will then be used by the dapp in 2 different modes (invisible iframe and popup window). The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. -In iframe node the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapp for embedding the visible iframe and tricking the user into clicking the confirm button. -If the dapp requires to make an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. +In the iframe node, the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapps from embedding the invisible iframe and tricking the user into clicking the confirm button. +If the dapp requires an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. -In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign``` as there is no way to display to the user the meaningfull content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses as well the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. +In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign```, as there is no way to display to the user the meaningful content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses, as well as the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. -The html page also check for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time. +The html page also checks for the availability of the "personal" api and if so, will ask the user to unlock the account if necessary. The unlocking is temporary (3s) so the password will be asked again if a transaction is attempted before the end of this short time. In both iframe mode and window mode, the communication with the dapp is achieved using ```window.postMessage```. -The fist message the iframe/window send is a message containing the string "ready" to let the dapp know that it now accepts messages. Then the dapp can start performing rpc call by sending message using the following object : +The fist message the iframe/window sends is a message containing the string "ready" to let the dapp know that it now accepts messages. Then the dapp can start performing rpc call by sending message using the following object : ``` { id:
, //so responses can be match as there is no guarantee of the order of the response @@ -94,14 +94,14 @@ Rationale The design for that proposal was chosen for its simplicity and security. A previous idea was to use an oauth-like protocol in order for the user to accept or deny a transaction request. It would have required deeper code change in the node and some geth contributors argues that such change did not fit into geth code base as it would have required dapp aware code. The current design, instead has a very simple implementation (self contained html file that can be shared across node's implementation) and its safeness is guarantess by browsers' cross domain policies. -The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allow the dapp to execute read only calls without the need for user input and the window ensure the user approve before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser ```window.confirm``` dialog, this would have prevented the use of a more elegant confirmation popup that the current design allow. It also happen to be that the ```window.confirm``` is not safe in some browser as it give focus to the accept option and can be triggered automatically (https://bugs.chromium.org/p/chromium/issues/detail?id=260653). +The use of iframe/ window was required to have both security and user friendliness. The invisble iframe allows the dapp to execute read only calls without the need for user input, and the window ensures user approval before making a call. While we could have made it without the window mode by making the iframe confirmation use the native browser ```window.confirm``` dialog, this would have prevented the use of a more elegant confirmation popup that the current design allows. It also happens to be that the ```window.confirm``` is not safe in some browsers, as it gives focus to the accept option and can be triggered automatically (https://bugs.chromium.org/p/chromium/issues/detail?id=260653). Implementations =============== -In order to implement this design, the following html file or an equivalent one need to be served at the url \/authorization.html +In order to implement this design, the following html file or an equivalent one needs to be served at the url \/authorization.html -That's it +That's it. ``` @@ -610,4 +610,4 @@ That's it -``` \ No newline at end of file +``` From 4fa9b321c035424d788b56b172755984af212bad Mon Sep 17 00:00:00 2001 From: wighawag Date: Thu, 12 May 2016 17:14:58 +0100 Subject: [PATCH 14/16] fix spelling --- EIPS/eip-XXX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-XXX.md b/EIPS/eip-XXX.md index db829030..d183d4b2 100644 --- a/EIPS/eip-XXX.md +++ b/EIPS/eip-XXX.md @@ -51,7 +51,7 @@ This file will then be used by the dapp in 2 different modes (invisible iframe a The invisible iframe will be embeded in the dapp to allow the dapp to send its read-only rpc call without having to enable CORS for the dapp's website domain. This is done by sending message to the iframe (via javascript ```window.postMessage```) which in turn execute the rpc call. This works since the iframe and the node share the same domain/port. -In the iframe node, the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapps from embedding the invisible iframe and tricking the user into clicking the confirm button. +In the iframe mode, the html file's javascript code will ensure that no call requiring an unlocked key can be made. This is to prevent dapps from embedding the invisible iframe and tricking the user into clicking the confirm button. If the dapp requires an ```eth_sendTransaction``` call, the dapp will instead open a new window using the same url. In this popup window mode, the html file's javascript code will alow ```eth_sendTransaction``` (but not ```eth_sign```, as there is no way to display to the user the meaningful content of the transaction to sign in a safe way) to be called. But instead of sending the call to the node directly, a confirmation dialog will be presented showing the sender and recipient addresses, as well as the amount being transfered along with the potential gas cost. Upon the user approving, the request will be sent and the result returned to the dapp. An error will be returned in case the user cancel the request. From 3c1c997f3d3c042f0da6b983697f29d18794926c Mon Sep 17 00:00:00 2001 From: wighawag Date: Mon, 17 Apr 2017 22:30:40 +0530 Subject: [PATCH 15/16] rename to eip-107 --- EIPS/{eip-XXX.md => eip-107.md} | 7 ++++--- EIPS/{eip-XXX => eip-107}/authorization-locked.png | Bin .../{eip-XXX => eip-107}/authorization-password.png | Bin EIPS/{eip-XXX => eip-107}/authorization.png | Bin 4 files changed, 4 insertions(+), 3 deletions(-) rename EIPS/{eip-XXX.md => eip-107.md} (99%) rename EIPS/{eip-XXX => eip-107}/authorization-locked.png (100%) rename EIPS/{eip-XXX => eip-107}/authorization-password.png (100%) rename EIPS/{eip-XXX => eip-107}/authorization.png (100%) diff --git a/EIPS/eip-XXX.md b/EIPS/eip-107.md similarity index 99% rename from EIPS/eip-XXX.md rename to EIPS/eip-107.md index ba13a3ca..96374488 100644 --- a/EIPS/eip-XXX.md +++ b/EIPS/eip-107.md @@ -5,6 +5,7 @@ Created: 2016-06-05 Status: Draft Type: Standard + Category: Interface
Abstract @@ -28,19 +29,19 @@ Account unlocked : ----------------- When the account is already unlocked, the user is presented with the following popup for every transaction that the dapp attempts to make : - + Account locked and no "personal" api exposed via rpc: ----------------- When the account is locked and the node do not provide access to account unlocking via its rpc interface, the following popup will be presented. This is not ideal since this require the user to know how to unlock an account: - + Account locked but node exposing the "personal" api via rpc : ----------------- A better option is to ask the user the password but this is only possible if the node allow access to the "personal" api via rpc. In such case the following dialog will be presented to the user so he/she can accept the transaction by providing the password required to unlock the account: - + Specification diff --git a/EIPS/eip-XXX/authorization-locked.png b/EIPS/eip-107/authorization-locked.png similarity index 100% rename from EIPS/eip-XXX/authorization-locked.png rename to EIPS/eip-107/authorization-locked.png diff --git a/EIPS/eip-XXX/authorization-password.png b/EIPS/eip-107/authorization-password.png similarity index 100% rename from EIPS/eip-XXX/authorization-password.png rename to EIPS/eip-107/authorization-password.png diff --git a/EIPS/eip-XXX/authorization.png b/EIPS/eip-107/authorization.png similarity index 100% rename from EIPS/eip-XXX/authorization.png rename to EIPS/eip-107/authorization.png From f412381dc9ec50f0bd3a8ef34d2558e3fb88f81f Mon Sep 17 00:00:00 2001 From: wighawag Date: Wed, 19 Apr 2017 10:31:14 +0530 Subject: [PATCH 16/16] set EIP number to 107 --- EIPS/eip-107.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-107.md b/EIPS/eip-107.md index bb45ab7e..2054368a 100644 --- a/EIPS/eip-107.md +++ b/EIPS/eip-107.md @@ -1,5 +1,5 @@
-  EIP: draft
+  EIP: 107
   Title: safe "eth_sendTransaction" authorization via html popup
   Author: Ronan Sandford 
   Created: 2016-06-05