风险提示:理性看待区块链,提高风险意识!
本体网络智能合约安全与漏洞分析:存储注入攻击
首页 > 币界资讯 > 区块链知识 2019-11-03 14:58:33
币界网报道:

在上面两期中,我们介绍了在本体上开发智能合约可能会遇到的两种安全威胁:跨合约调用攻击强制交易失败攻击,并针对这两种安全威胁给出了相应的解决方案。为了更好地帮助合约开发者规避这些安全漏洞,我们将持续收集这些可能会产生安全威胁的合约案例。同时,社区开发者如果在本体上进行智能合约开发时遇到其它的安全威胁,可以和我们一起探讨,一起共同打造更加安全的智能合约体系。

image.png

这一期将介绍开发智能合约过程中可能遇到的另外一种安全威胁:存储注入攻击。在详细介绍这种安全威胁前,我们先介绍下本体的智能合约持久化存储接口 :

def Put(context, key, value)

该接口主要包含下列三个参数:

1. context - 当前智能合约的运行的上下文环境,一般情况下为当前智能合约 hash;

2. key - 当前需要存储数据的 key 值;

3. value - 当前需要存储数据的 value 值。

正常情况下,开发者使用这个接口存储持久化数据时不会有问题,但是在一些复杂应用下,可能会存在安全威胁而被攻击的情况。

存储注入攻击

开发者在编写智能合约时,通常需要使用持久化存储去存放一些需要被多次使用的数据。这时,开发者就需要调用智能合约底层提供的持久化存储方法去存储这些数据。为了更好的说明这个问题,这里我们列举一个大家比较熟悉的例子。

当我们需要发布某个符合 OEP-4协议的 token 时,需要实现 OEP-4协议中的所有接口。这里,为了简化示例,我们只列举其中的两个方法:transfer() totalSupply()

SUPPLY_KEY = 'TotalSupply'
def transfer(from_acct, to_acct,amount):
    """
    Transfer amount of tokens from from_acct to to_acct
    :param from_acct: the account from which the amount of tokens will be transferred
    :param to_acct: the account to which the amount of tokens will be transferred
    :param amount: the amount of the tokens to be transferred, >= 0
    :return: True means success, False or raising exception means failure.
    """
    if CheckWitness(from_acct) == False or amount < 0:
        return False
    fromBalance = Get(ctx, from_acct)
    if amount > fromBalance:
        return False
    if amount == fromBalance:
        Delete(ctx, from_acct)
    else:
        Put(ctx,from_acct, fromBalance - amount)
    toBalance = Get(ctx, to_acct)
    Put(ctx, to_acct, toBalance + amount)
    TransferEvent(from_acct, to_acct, amount)
return True
def totalSupply():
    """
    :return: the total supply of the token
    """
returnGet(ctx,SUPPLY_KEY)

粗略来看,这两个方法没有任何问题,transfer()方法主要实现 from_acct 地址到 to_acct 地址的转账功能,totalSupply()主要实现获取当前资产的总发行量功能。但是,若仔细查看transfer()方法里的实现,可以发现该方法并没有对 to_acct 地址做任何的检查。

假如这时恶意用户提供的 to_acct 地址并不是正常的地址,而是一些其他的字符串,例如:“TotalSupply”等,那么此时在获取当前资产发行量时就会不准确。这看起来危害程度是有限的,因为我们只列举了这两个方法。但是若这本智能合约中使用了其它持久化存储,所有的持久化存储可能都会产生影响。

存储注入攻击的防范

对于这种合约攻击,智能合约开发者如何去防范?可以看到,主要的问题还是在持久化存储的 key 值上,我们可以将 Put 中的 key 分为两类:

静态 key 值 - key 值直接在合约内部定义的值;

动态 key 值 - key 值需要从外部传入的值。

对于静态 key,因为在合约内部定义,所以并不会有变动。而动态的 key 值由于从外部传入,所以 key 值不可预测。在某些特殊的情况下,若动态的 key 值和某个静态 key 值相同,就会形成我们上面所说的存储注入攻击的情况。针对这种情况,开发者可以为 key 值增加 prefix 字段来防范这种攻击。

SUPPLY_KEY = 'TotalSupply'
BALANCE_PREFIX = bytearray(b'\x01')
def transfer(from_acct, to_acct, amount):
    """
    Transfer amount of tokens from from_acct to to_acct
    :param from_acct: the account from which the amount of tokens will be transferred
    :param to_acct: the account to which the amount of tokens will be transferred
    :param amount: the amount of the tokens to be transferred, >= 0
    :return: True means success, False or raising exception means failure.
    """
    if CheckWitness(from_acct) == False or amount < 0:
        return False
    fromKey = concat(BALANCE_PREFIX, from_acct)
    fromBalance = Get(ctx, fromKey)
    if amount > fromBalance:
        return False
    if amount == fromBalance:
        Delete(ctx, fromKey)
    else:
        Put(ctx, fromKey, fromBalance - amount)
    toKey = concat(BALANCE_PREFIX, to_acct)
    toBalance = Get(ctx, toKey)
    Put(ctx, toKey, toBalance + amount)
    TransferEvent(from_acct, to_acct, amount)
return True
def totalSupply():
    """
    :return: the total supply of the token
    """
returnGet(ctx,SUPPLY_KEY)

可以看到,我们为动态传入的 to_acct 地址在持久化存储时增加了 prefix 字段。这样在存储时,就不会出现和其它持久化存储混乱的情况。当然,更好的做法可以给所有的持久化存储都加上 prefix 字段。这个例子中,由于只有两个持久化存储,我们只需要保证它们互相不受影响即可。

后记

以上我们讲解了第三种在本体上开发智能合约时可能遇到的安全威胁,并给出了相关解决方案。另外,本体智能合约开发者可以使用本体智能合约集成开发环境 SmartX 中深度集成的高度自动化智能合约形式化验证平台 VaaS-ONT 来“一键式”精确定位到有风险的代码位置,迅速找出原因,有效验证智能合约或区块链应用的常规安全漏洞、安全属性和功能正确性,从而显著提高安全等级。

上一篇: 本体网络智能合约安全与漏洞分析:边界攻击
下一篇: 本体网络智能合约安全与漏洞分析:跨合约调用攻击
推荐专栏
Boss Wallet Web3 Econom Pass
专注币圈最新资讯
通俗浅显地聊透Web3大事小情
读懂区块链生态与未来,尽在币界网!
热门币种
更多
币种
美元价格
24H涨跌幅
BTC比特币
60,963.61 USDT
¥435,103.38
-2.72%
ETH以太坊
3,368.69 USDT
¥24,042.67
-0.3%
BNB币安币
570.68 USDT
¥4,073.00
-0.28%
USDT泰达币
1.02 USDT
¥7.25
-0.19%
SOL
135.96 USDT
¥970.36
+7.66%
USDC
1.00 USDT
¥7.15
-0.01%
TON
7.59 USDT
¥54.14
+4.55%
XRP瑞波币
0.47720 USDT
¥3.41
+0.48%
DOGE狗狗币
0.12210 USDT
¥0.87140
+2.43%
ADA艾达币
0.39050 USDT
¥2.79
+3.88%
热搜币种
更多
币种
美元价格
24H涨跌幅
比特币
61034.17 USDT
¥443,407.14
-1.54%
Solana
137.36 USDT
¥997.91
-0.91%
Filecoin
4.3477 USDT
¥31.59
-2.19%
Curve
0.296 USDT
¥2.15
-6.71%
柚子
0.5733 USDT
¥4.16
-0.28%
Terra Classic
8.173E-5 USDT
¥0.00
-1.28%
Shiba Inu
1.72E-5 USDT
¥0.00
-3.75%
Conflux
0.1558 USDT
¥1.13
-1.64%
狗狗币
0.1223 USDT
¥0.89
-3.78%
dYdX
1.3774 USDT
¥10.01
-1.18%
Arweave
25.8768 USDT
¥187.99
-10.03%
Uniswap
9.2944 USDT
¥67.52
-2.17%
最新快讯
更多
已有超89%的BLAST空投被领取,领取地址超25万
2024-06-27 11:54:22
新SwellrswETH池已上线Penpie
2024-06-27 11:34:46
Custodia要求上诉法院指示地区法院撤销对Custodia主账户的拒绝
2024-06-27 11:26:52
Custodia寻求法官撤回授权美联储拒绝其主账户申请的决定
2024-06-27 11:26:52
XT即将上线新一期鲨鱼鳍理财
2024-06-27 11:26:33
WEEX唯客将于7月1日开启第二期Launchpool,投入WXT瓜分37,000ZK
2024-06-27 11:25:57
币界网实时价格午报:PEPE站上0.000012722美元/枚,涨幅达3.03%
2024-06-27 11:23:47
下载币界网APP