mirror of https://github.com/status-im/EIPs.git
109 lines
4.9 KiB
Markdown
109 lines
4.9 KiB
Markdown
---
|
|
eip: 1102
|
|
title: Opt-in provider access
|
|
author: Paul Bouchon <mail@bitpshr.net>
|
|
discussions-to: https://ethereum-magicians.org/t/eip-1102-opt-in-provider-access/414
|
|
status: Draft
|
|
type: Standards Track
|
|
category: Interface
|
|
created: 2018-05-04
|
|
---
|
|
|
|
## Simple summary
|
|
|
|
This proposal describes a way for DOM environments to expose an Ethereum provider API that requires user approval.
|
|
|
|
## Abstract
|
|
|
|
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 protocol in which dapps request access to an Ethereum provider API.
|
|
|
|
## Specification
|
|
|
|
### Typical dapp initialization
|
|
|
|
```
|
|
START dapp
|
|
IF web3 is defined
|
|
CONTINUE dapp
|
|
IF web3 is undefined
|
|
STOP dapp
|
|
```
|
|
|
|
### Proposed dapp initialization
|
|
|
|
```
|
|
START dapp
|
|
REQUEST[1] provider
|
|
IF user approves
|
|
RESPOND[2] with provider
|
|
CONTINUE dapp
|
|
IF user rejects
|
|
IF non-Ethereum environment
|
|
NOOP[3]
|
|
```
|
|
|
|
#### `[1] REQUEST`
|
|
|
|
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" and an optional `id` property corresponding to an identifier of a specific wallet provider, such as "METAMASK".
|
|
|
|
#### `[2] RESPOND`
|
|
|
|
Ethereum-enabled DOM environments MUST respond with an Ethereum provider API by emitting an "ethereumprovider" [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent) on the `window` object. This custom event MUST pass a provider API as an `ethereum` property on its `detail` data object.
|
|
|
|
#### `[3] NOOP`
|
|
|
|
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 Ethereum-enabled environments on other platforms would most likely use platform-specific native messaging protocols, not `postMessage`.
|
|
|
|
```js
|
|
window.addEventListener('load', () => {
|
|
// Listen for provider response
|
|
window.addEventListener('ethereumprovider', async ({ detail: { ethereum } }) => {
|
|
// Provider API exposed, continue
|
|
const networkVersion = await ethereum.send('net_version', []);
|
|
});
|
|
// Request provider
|
|
window.postMessage({ type: 'ETHEREUM_PROVIDER_REQUEST' }, '*');
|
|
});
|
|
```
|
|
|
|
## Rationale
|
|
|
|
The pattern of provider auto-injection followed by the previous generation of Ethereum-enabled DOM environments 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
|
|
|
|
* 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 provider API access on untrusted sites to prevent fingerprinting.
|
|
|
|
### Long-term value-add
|
|
|
|
* Dapps could request specific account information based on user consent.
|
|
* Dapps could request specific user information based on user consent (uPort, DIDs).
|
|
* Dapps could request a specific network based on user consent.
|
|
* Dapps could request multiple instances of the above based on user consent.
|
|
|
|
## Backwards compatibility
|
|
|
|
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/pull/4703) of the strategy described above and expects to begin limited user testing soon.
|
|
|
|
## Copyright
|
|
|
|
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|