DeFiVulnLabs靶场全系列详解(三十四)预言机产生了过时的价格

admin 2025年5月5日19:22:17评论2 views字数 3596阅读11分59秒阅读模式
01
前言
        此内容仅作为展示Solidity常见错误的概念证明。它严格用于教育目的,不应被解释为鼓励或认可任何形式的非法活动或实际的黑客攻击企图。所提供的信息仅供参考和学习,基于此内容采取的任何行动均由个人全权负责。使用这些信息应遵守适用的法律、法规和道德标准。
    DeFiVulnLabs一共有47个漏洞实验,包括各种经典的合约漏洞和一些少见的可能造成安全问题的不安全代码,本系列将逐一解析每个漏洞,包括官方的解释和自己的理解。
02
预言机产生了过时的价格
什么是预言机?

    Oracle预言机充当智能合约与外部世界之间的桥梁,它们可以从外部获取数据,并将这些数据传递给智能合约

    智能合约在接收到来自预言机的数据后,可以根据这些数据执行相应的逻辑。

漏洞解析:
    代码利用了chainlink(一个商业预言机)来获取价格,但是实际上这个价格获取后可能并未再次进行验证。所以这个价格可能是过期的,需要校验预言机返回数据的有效性是非常有必要的。不能盲目的相信预言机获取的数据。
代码解析:https://github.com/SunWeb3Sec/DeFiVulnLabs/blob/main/src/test/Oracle-stale.sol
第一段代码
去复制主网的区块17568400地址为0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419的数据信息
contract ContractTest is Test {    AggregatorV3Interface internal priceFeed;    function setUp() public {        vm.createSelectFork("mainnet"17568400);        priceFeed = AggregatorV3Interface(            0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419        ); // ETH/USD    }
    主要的代码是在testUnSafePrice方法,这里直接调用了priceFeed.latestRoundData()来获取数据,并且没有进行任何的验证,

function testUnSafePrice() public {       //没有经过二次的校验        (, int256 answer, , , ) = priceFeed.latestRoundData();        emit log_named_decimal_int("price", answer, 8);    }

而像testSafePrice经过了一些校验来确保来源于预言机的数据是正确的且不是过时的。
function testSafePrice() public {        (            uint80 roundId,            int256 answer,            ,            uint256 updatedAt,            uint80 answeredInRound        ) = priceFeed.latestRoundData();        /*        Mitigation:        answeredInRound: The round ID in which the answer was computed        updatedAt: Timestamp of when the round was updated        answer: The answer for this round        */        require(answeredInRound >= roundId, "answer is stale");        require(updatedAt > 0"round is incomplete");        require(answer > 0"Invalid feed answer");        emit log_named_decimal_int("price", answer, 8);    }
    以下代码定义了一个接口AggregatorV3Interface,里面存在一个函数latestRoundData用于获取最新的价格数据
interface AggregatorV3Interface {functionlatestRoundData()externalviewreturns(            uint80 roundId,            int256 answer,            uint256 startedAt,            uint256 updatedAt,            uint80 answeredInRound        );}
answeredInRound:预言机返回的ID,回复1次则加1
updatedAt:回合更新的时间戳
answer:这一轮的的预言机的返回价格
全部的代码
contract ContractTest is Test {    AggregatorV3Interface internal priceFeed;functionsetUp() public{        vm.createSelectFork("mainnet"17568400);        priceFeed = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419        ); // ETH/USD    }functiontestUnSafePrice() public{//Chainlink oracle data feed is not sufficiently validated and can return stale price.        (, int256 answer, , , ) = priceFeed.latestRoundData();        emit log_named_decimal_int("price", answer, 8);    }functiontestSafePrice() public{        (            uint80 roundId,            int256 answer,            ,            uint256 updatedAt,            uint80 answeredInRound        ) = priceFeed.latestRoundData();/*        Mitigation:        answeredInRound: The round ID in which the answer was computed        updatedAt: Timestamp of when the round was updated        answer: The answer for this round        */require(answeredInRound >= roundId, "answer is stale");require(updatedAt > 0"round is incomplete");require(answer > 0"Invalid feed answer");        emit log_named_decimal_int("price", answer, 8);    }    receive() external payable {}}
03
漏洞解析
首先进入地址:
https://etherscan.io/address/0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
可以看到其实预言机已经给了我们返回的可校验的值了,通过这些值我们可以确定预言机返回的值不是过期的。
    roundId:检索数据的轮次ID,结合了一个阶段以确保随着时间的推移,轮次ID会变大

    answer:答案,也就我们要的值

    updatedAt:答案最后更新的时间戳

DeFiVulnLabs靶场全系列详解(三十四)预言机产生了过时的价格

可以看到正常情况下,不会有任何的区别,但是实际上可能会因为网络延迟,或者一些大幅度的涨跌幅而影响实际的值。

DeFiVulnLabs靶场全系列详解(三十四)预言机产生了过时的价格
04
如何修复该问题
上面代码已经给出了答案,就是获取返回值的时候不仅仅是获取结果的返回值(价格),而是获取结果的同时进行一些额外的校验。
require(answeredInRound >= roundId, "answer is stale");require(updatedAt > 0"round is incomplete");require(answer > 0"Invalid feed answer");
总的来说这个点也不一定是能被称为漏洞,而是说一种潜在的安全风险。
05
感谢关注
个人语雀账号:https://www.yuque.com/iceqaq

原文始发于微信公众号(Ice ThirdSpace):DeFiVulnLabs靶场全系列详解(三十四)预言机产生了过时的价格

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月5日19:22:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   DeFiVulnLabs靶场全系列详解(三十四)预言机产生了过时的价格https://cn-sec.com/archives/4030172.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息