EIP-2255: 钱包权限系统
用于限制对敏感方法访问的接口
Authors | Dan Finlay (@danfinlay), Erik Marks (@rekmarks), Gavin John (@Pandapip1) |
---|---|
Created | 2019-08-22 |
Requires | EIP-1193 |
Table of Contents
摘要
此 EIP 添加了两个新的钱包命名空间 RPC 端点 wallet_getPermissions
和 wallet_requestPermissions
,为请求和检查权限提供了一个标准接口。
动机
钱包负责通过适当的用户同意来协调不受信任的应用程序和用户密钥之间的交互。如今,钱包总是提示用户执行每个操作。这以巨大的用户摩擦为代价提供了安全性。我们认为,单个权限请求可以实现相同级别的安全性,并大大改善用户体验。
权限请求的模式(通常使用 Oauth2)在网络上很常见,使其成为一种非常熟悉的模式:
如今,许多 web3 应用程序都以一系列重复的请求开始其会话:
- 向此站点显示您的钱包地址。
- 切换到首选网络。
- 签署密码学挑战。
- 授予我们的合约代币津贴。
- 向我们的合约发送交易。
其中许多(可能全部),以及更多(如解密),都可以概括为原始登录屏幕上的一组人类可读的权限提示,并且可以仅在需要时请求其他权限:
这些权限中的每一个都可以被单独拒绝,甚至可以被_削弱_——调整以满足用户的条款(例如,登录请求可以具有用户添加的到期日期,并且代币津贴可以在请求时由用户调整)。
规范
本文档中的关键词“必须 (MUST)”,“禁止 (MUST NOT)”,“需要 (REQUIRED)”,“应该 (SHALL)”,“不应该 (SHALL NOT)”,“推荐 (RECOMMENDED)”,“可以 (MAY)”,“可选 (OPTIONAL)”应按照 RFC 2119 中的描述进行解释。
此提案向钱包的 web3 provider API 添加了两种新方法:wallet_getPermissions
和 wallet_requestPermissions
。
wallet_getPermissions
wallet_getPermissions
方法用于获取当前权限的数组(默认为空)。它不带任何参数,并返回一个 Permission
对象数组。
wallet_getPermissions
返回值
返回的权限格式必须是 Permission
对象的数组,其定义如下:
interface Caveat {
type: string;
value: any;
}
interface Permission {
invoker: string;
parentCapability: string;
caveats: Caveat[];
}
invoker
是一个 URI,用于标识当前 dapp 的来源(例如 https://your-site.com/
)。术语 parentCapability
是指正在被允许的方法(例如 eth_accounts
)。caveats
数组表示应用于允许方法的特定限制。Caveat
的 type
是一个字符串,value
是一个任意 JSON 值。Caveat
的 value
仅在 Caveat
的 type
的上下文中才有意义。
wallet_requestPermissions
wallet_requestPermissions
方法用于应用程序请求其他权限。它必须接受一个参数,即 PermissionRequest
对象,并且必须返回一个 RequestedPermission
对象数组。
wallet_requestPermissions
参数
wallet_requestPermissions
方法接受一个参数,即 PermissionRequest
对象,其定义如下:
interface PermissionRequest {
[methodName: string]: {
[caveatName: string]: any;
};
}
methodName
是正在请求其权限的方法的名称(例如 eth_accounts
)。caveatName
是应用于权限的 caveat 名称(例如 requiredMethods
)。caveat 值是 caveat 的值(例如 ["signTypedData_v3"]
)。
在发出 wallet_requestPermissions
请求并获得用户接受之前,对受限方法的尝试请求必须失败并显示错误。
如果 wallet_requestPermissions
请求被拒绝,则应按照 EIP-1193 抛出一个 code
值为 4001
的错误。
wallet_requestPermissions
返回值
wallet_requestPermissions
方法返回一个 RequestedPermission
对象数组,其定义如下:
interface RequestedPermission {
parentCapability: string;
date?: number;
}
parentCapability
是正在请求其权限的方法的名称(例如 eth_accounts
)。date
是请求的时间戳,以 Unix 时间表示,并且是可选的。
理由
虽然目前在每个操作的基础上获得用户同意的模型具有很高的安全性,但是通过获得更广泛的用户同意可以涵盖广泛的使用类别,可以用更易于理解的方式表达,从而获得巨大的可用性提升。这种模式可以为 web3 钱包中的不同功能提供各种好处。
requestPermissions
方法可以扩展为包括与请求的权限相关的其他选项,例如,站点可以请求具有特定功能的帐户。例如,像交易所这样需要 signTypedData_v3
(某些硬件钱包不支持)的网站可能希望指定该要求。这将允许钱包仅显示兼容的帐户,同时保留用户对于如何存储其密钥的隐私和选择。
测试用例
请求权限
以下示例应提示用户批准 eth_accounts
权限,如果获得批准,则返回权限对象。
provider.request({
method: 'requestPermissions',
params: [
{
'eth_accounts': {
requiredMethods: ['signTypedData_v3']
}
}
]
});
获取权限
以下示例应返回当前权限对象。
provider.request({
method: 'getPermissions'
});
安全考虑
服务器端请求伪造 (SSRF)
如果将显示网站的网站图标,则此注意事项适用。
钱包应注意不要对 URL 发出任意请求。因此,建议钱包通过将特定方案和端口列入白名单来清理 URI。例如,一个易受攻击的钱包可能会被诱骗修改本地托管的 redis 数据库中的数据。
版权
版权及相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Dan Finlay (@danfinlay), Erik Marks (@rekmarks), Gavin John (@Pandapip1), "EIP-2255: 钱包权限系统," Ethereum Improvement Proposals, no. 2255, August 2019. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2255.