From 26a4fbc197f129324e3f8c4939e388590a379362 Mon Sep 17 00:00:00 2001 From: Paul Bouchon Date: Tue, 3 Jul 2018 09:56:21 -0400 Subject: [PATCH] Automatically merged updates to draft EIP(s) 1102 Hi, I'm a bot! This change was automatically merged because: - It only modifies existing Draft or Last Call EIP(s) - The PR was approved or written by at least one author of each modified EIP - The build is passing --- EIPS/eip-1102.md | 77 +++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/EIPS/eip-1102.md b/EIPS/eip-1102.md index 7d12c6c5..e8d4b564 100644 --- a/EIPS/eip-1102.md +++ b/EIPS/eip-1102.md @@ -1,6 +1,6 @@ --- eip: 1102 -title: Opt-in web3 access +title: Opt-in provider access author: Paul Bouchon discussions-to: https://ethereum-magicians.org/t/opt-in-web3-access/414 status: Draft @@ -11,13 +11,13 @@ created: 2018-05-04 ## Simple summary -This proposal describes a new way for DOM environments to expose the web3 API that requires user approval. +This proposal describes a way for DOM environments to expose an Ethereum provider API that requires user approval. ## Abstract -MetaMask and most other tools that provide access to web3-enabled environments do so automatically and without user consent. This exposes users of such environments to fingerprinting attacks since untrusted websites can check for a `web3` object and reliably identify web3-enabled clients. +The previous generation of Ethereum-enabled DOM environments follows a pattern of directly injecting a provider object into the DOM without user consent. This exposes users of such environments to fingerprinting attacks since untrusted websites can check for the injected provider and reliably identify Ethereum-enabled clients. -This proposal outlines a new protocol in which dapps request access to the web3 API instead of relying on its preexistence in a given DOM environment. +This proposal outlines a protocol in which dapps request access to an Ethereum provider API. ## Specification @@ -35,69 +35,60 @@ IF web3 is undefined ``` START dapp -IF web3 is defined - CONTINUE dapp -IF web3 is undefined - REQUEST[1] web3 API +REQUEST[1] Ethereum provider IF user approves - INJECT[2] web3 API - NOTIFY[3] dapp + NOTIFY[2] dapp CONTINUE dapp IF user rejects - IF non-web3 environment - NOOP[4] + IF non-Ethereum environment + NOOP[3] ``` #### `[1] REQUEST` -Dapps MUST request the web3 API by sending a message using [`window.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) API. This message MUST be sent with a payload object containing a `type` property with a value of “WEB3_API_REQUEST” and an optional `id` property corresponding to an identifier of a specific wallet provider, such as "METAMASK". +Dapps MUST request an Ethereum provider API by sending a message using the [`window.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) API. This message MUST be sent with a payload object containing a `type` property with a value of `ETHEREUM_PROVIDER_REQUEST`. -#### `[2] INJECT` +#### `[2] NOTIFY` -Dapp browsers should inject the web3 API using an implementation-specific strategy that can expose the web3 API to the user’s browser context, such as HTML script tag injection. +Ethereum-enabled DOM environments MUST notify dapps of successful provider API exposure by sending a message using the [`window.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) API. This message MUST be sent with a payload object containing a `type` property with a value of `ETHEREUM_PROVIDER_SUCCESS` and an `ethereum` property containing an Ethereum provider object that conforms to [ethereum/interfaces#16](https://github.com/ethereum/interfaces/issues/16). -#### `[3] NOTIFY` +#### `[3] NOOP` -Dapps browsers MUST notify dapps of successful web3 exposure by sending a message using [`window.postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) API. This message MUST be sent with a payload object containing a `type` property with a value of “WEB3_API_SUCCESS" and an optional `id` property corresponding to an identifier of a specific wallet provider, such as "METAMASK". - -#### `[4] NOOP` - -If a user rejects web3 access on an untrusted site, the site itself MUST NOT be notified in any way; notification of a rejection would allow third-party tools to still identify that a client is web3-enabled despite not being granted web3 access. +If a user rejects access to the Ethereum provider API on an untrusted site, the site itself MUST NOT be notified in any way; notification of a rejection would allow third-party tools to still identify that a client is Ethereum-enabled despite not being granted access to any provider API. ### Example implementation: `postMessage` -The following example demonstrates one possible implementation of this strategy in a browser-based DOM environment. Note that web3 environments on other platforms would most likely use platform-specific native messaging protocols, not `postMessage`. +The following example demonstrates one possible implementation of this strategy in a browser-based DOM environment. Note that Ethereum-enabled environments on other platforms would most likely use platform-specific native messaging protocols, not `postMessage`. ```js -if (typeof web3 !== 'undefined') { - // web3 API defined, start dapp -} else { - window.addEventListener('message', function (event) { - if (!event.data || !event.data.type) { return; } - if (event.data.type === 'WEB3_API_SUCCESS') { - // web3 API defined, start dapp - } - }); - // request web3 API - window.postMessage({ type: 'WEB3_API_REQUEST' }); -} +// Listen for provider API +window.addEventListener('message', function (event) { + if (!event.data || !event.data.type) { return; } + if (event.data.type === 'ETHEREUM_PROVIDER_SUCCESS') { + // Provider API exposed, continue + const networkVersion = await event.data.ethereum.send('net_version', []); + console.log(networkVersion); + } +}); +// Request Provider API +window.postMessage({ type: 'ETHEREUM_PROVIDER_REQUEST' }); ``` ## Rationale -An [open issue](https://github.com/MetaMask/metamask-extension/issues/714) against the [MetaMask](https://github.com/MetaMask/metamask-extension) extension has received community upvotes and Richard Burton of the [Balance](https://github.com/balance-io) team published a well-received [blog post](https://medium.com/@ricburton/metamask-walletconnect-js-b47857efb4f7) discussing these potential changes. +The pattern of provider auto-injection followed by the previous generation of Ethereum-enabled DOM environements failed to protect user privacy by allowing untrusted websites to uniquely identify Ethereum users. This proposal establishes a new pattern wherein dapps must request access to an Ethereum provider API. This protocol directly prevents fingerprinting attacks by giving users the ability to reject provider exposure on a given website. ### Constraints -* Web3 MUST NOT be exposed to websites by default. -* Dapps MUST request web3 if it does not exist. -* Users MUST be able to approve or reject web3 access. -* Web3 MUST be exposed to websites after user consent. -* Environments MAY continue auto-exposing web3 if users can disable this behavior. +* A provider API MUST NOT be exposed to websites by default. +* Dapps MUST request a provider API if it does not exist. +* Users MUST be able to approve or reject provider API access. +* A provider API MUST be exposed to websites after user consent. +* Environments MAY continue auto-exposing a provider API if users can opt-out. ### Immediate value-add -* Users can reject web3 access on untrusted sites to prevent web3 fingerprinting. +* Users can reject provider API access on untrusted sites to prevent fingerprinting. ### Long-term value-add @@ -108,11 +99,11 @@ An [open issue](https://github.com/MetaMask/metamask-extension/issues/714) again ## Backwards compatibility -This proposal impacts dapp authors and requires that they request access to the web3 API before using it. This proposal also impacts developers of web3-enabled environments or dapp browsers as these tools should no longer auto-expose the web3 API; instead, they should only do so if a website requests the API and if the user consents to its access. Environments may continue to auto-expose the web3 API as long as users have the ability to disable this behavior. +This proposal impacts dapp authors and requires that they request access to an Ethereum provider API before using it. This proposal also impacts developers of Ethereum-enabled environments or dapp browsers as these tools should no longer auto-expose any provider API; instead, they should only do so if a website requests a provider API and if the user consents to its access. Environments may continue to auto-expose an Ethereum provider API as long as users have the ability to disable this behavior. ## Implementation -The MetaMask team is currently working an [MVP implementation](https://github.com/MetaMask/metamask-extension/issues/3930) of the strategy described above and expects to begin limited user testing soon. +The MetaMask team is currently working an [MVP implementation](https://github.com/MetaMask/metamask-extension/pull/4703) of the strategy described above and expects to begin limited user testing soon. ## Copyright