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
This commit is contained in:
Paul Bouchon 2018-07-03 09:56:21 -04:00 committed by EIP Automerge Bot
parent a9975c84e8
commit 26a4fbc197

View File

@ -1,6 +1,6 @@
---
eip: 1102
title: Opt-in web3 access
title: Opt-in provider access
author: Paul Bouchon <mail@bitpshr.net>
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 users 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