parity再爆多重签名合约漏洞

多重签名是团队资金保管的一个常见方式,在功能、易用性和安全性上,BTS的多重签名功能无疑是个中翘楚。

昨天以太坊客户端parity再出爆出多重签名漏洞。简书作者菠菜philsong看了安全公告后,马上分析了代码:https://etherscan.io/address/0x863df6bfa4469f3ead0be8f9f2aae51c91a907b4#code,发现漏洞由如下代码段引起:

// constructor - just pass on the owner array to the multiowned and

// the limit to daylimit

function initWallet(address[ ] _owners, uint _required, uint _daylimit) only_uninitialized {

initDaylimit(_daylimit);

initMultiowned(_owners, _required);

}

// constructor is given number of sigs required to do protected "onlymanyowners" transactions

// as well as the selection of addresses capable of confirming them.

function initMultiowned(address[ ] _owners, uint _required) only_uninitialized {

m_numOwners = _owners.length + 1;

m_owners[1] = uint(msg.sender);

m_ownerIndex[uint(msg.sender)] = 1;

for (uint i = 0; i < _owners.length; ++i)   {

m_owners[2 + i] = uint(_owners[i]);

m_ownerIndex[uint(_owners[i])] = 2 + i;

}

m_required = _required;

}

这个函数假定创建者会调用initWallet函数,但是initWallet根本没有任何鉴权,任何人都可以成为owner,然后就可以调用kill函数杀死合约自身。

 // kills the contract sending everything to _to.

function kill(address _to) onlymanyowners(sha3(msg.data)) external {

suicide(_to);

}

自杀之后,唯一可以用的函数只有

// gets called when no other function matches

function() payable {

// just being sent some cash?

if (msg.value > 0)

Deposit(msg.sender, msg.value);

}

其实在七月份parity就出现过类似的问题,Hi区块链当时也写了文章《BitShares|比特股账户权限和多重签名功能介绍》谈过这个问题。

现在看来有必要再谈一下bts/ 比特股是怎么处理多重签名的问题的。

在BitShares (比特股)中,每一个账户的权限可分为:

活跃权限: 控制资金

账户权限: 控制账户

备注密钥:读取备注

前两者者都可以通过钱包账户页面中权限标签进行设定。设定授权的职权实体 (详见下文)以及分配相应的权重。只有高于门槛阀值权重的职权实体才能签署有效的交易。

授权账户

在比特股系统中,一个职权实体通过一个或多个实体进行操作授权,比如转账或者交易。

一个职权实体由一个或多个账户名加权重组合构成。

参与签名的一个或多个实体的权重之和必须大于门槛阀值才能进行签署有效的交易动作。

举个例子,假设Alice,Bob,Charlie和Dennis管理一个共同基金。我们希望只要有2个人同意,我们就能构建一个有效的交易。也就是2-of-4 (N-of-M)模式,这个结构如下:

账户名权重
Alice33%
Bob33%
Charlie33%
Dennis33%
----------------
门槛阀值:51%

这4个成员每人都有33%的权重,但是门槛阀值设定在50%。这样,至少需要2名成员同意才能获得多余门槛阀值的权重以签署有效交易。

同理,要构建 3-of-4 结构,我们可以降低每个成员的权重值到 17%,或者增加门槛阀值到 99%。

(扁平结构) 灵活的多重签名

通过门槛阀值和权重,现在我们管理资金时拥有了更多的灵活性,更准确的说,我们拥有了更多的控制权。比如,我们可以分配不同的权重到不同的成员。假设Alice希望通过多重签名机制来提高资金安全性防范偷窃,但又不想给与她的朋友们过多的控制权,那么,我们可以设定这样的职权实体分布:

账户名权重
Alice49%
Bob25%
Charlie25%
Dennis10%
----------------
门槛阀值:51%

这样,Alice只需要任何一个朋友协助就能使用资金,或者其他3个朋友必须全部同意才能使用资金。

多层次灵活的多重签名

我们再来看一下一种简单的企业常用的多层级组织架构。这个公司有一个首席财务官,有多个部门向其汇报,如Treasurer, Controller, Tax Manager, Accounting等。公司的首席执行官也要求拥有支付权。我们可以这样设计职权实体结构:

账户名权重
CEO.COMPANY51%
CFO.COMPANY51%
------------------
门槛阀值:51%

而 CEO.COMPANY 和 CFO.COMPANY 则拥有各自的职权实体。比如 CFO.COMPANY 账户可设置如下:

CFO.COMPANY权重
Chief.COMPANY51%
Treasurer.COMPANY33%
Controller.COMPANY33%
Tax Manager.COMPANY10%
Accounting.COMPANY10%
-------------------------
门槛阀值:51%

这个设计允许:

首席执行官使用资金

首席财务官使用资金

Treasurer连同Controller一起可以使用资金

Controller或者Treasurer连同Tax Manager或者Accounting可以使用资金

这样,通过设计构建灵活的职权实体,从而拥有任意层级的结构,将满足绝大多数企业使用场景。

从实际效果来看,BTS的多重签名功能在功能、易用性和安全性上,无疑要出色的的多,从未出过问题。


声明:登载此文出于传递更多信息之目的,观点仅代表作者本人,绝不代表Hi区块链赞同其观点或证实其描述。

提示:投资有风险,入市须谨慎。本资讯不作为投资理财建议。