DeFiVulnLabs靶场全系列详解(三十八)结构体不完全的删除导致数据残留可能数据泄露

admin 2025年5月9日13:56:35评论4 views字数 2401阅读8分0秒阅读模式
01
前言
此内容仅作为展示Solidity常见错误的概念证明。它严格用于教育目的,不应被解释为鼓励或认可任何形式的非法活动或实际的黑客攻击企图。所提供的信息仅供参考和学习,基于此内容采取的任何行动均由个人全权负责。使用这些信息应遵守适用的法律、法规和道德标准。
DeFiVulnLabs一共有47个漏洞实验,包括各种经典的合约漏洞和一些少见的可能造成安全问题的不安全代码,本系列将逐一解析每个漏洞,包括官方的解释和自己的理解。
02
结构体不完全的删除导致数据残留

漏洞解析:

    solidity提供delete了关键字来删除数据,但是如果只是使用delete删除数据还是不完全的,不完全的使用delete函数来删除数据,可能会导致数据残留、数据泄露。

代码地址:

https://github.com/SunWeb3Sec/DeFiVulnLabs/blob/main/src/test/Struct-deletion.sol

代码解析:

    代码设置了一个Mapping的映射,在solidity里mapping是特殊的,当删除一个包含映射(mapping)的结构体时。

    而我们如果 使用 delete 关键字实际上只会重置结构体的基本字段,而不会删除结构体内部的映射,因此只能逐个删除其中的值,如果直接删除它的上层元素,则会残留。因为我们虽然还是要使用delete删除元素,但是需要做额外的处理。

pragma solidity ^0.8.0;contract StructDeletionBug {//设置一个结构  包含id 和flags {uint256:bool}    struct MyStruct {        uint256 id;        mapping(uint256 => bool) flags;    }    mapping(uint256 => MyStruct) public myStructs;//允许新增数据到MyStructs里function  addStruct(uint256 structId, uint256 flagKeys)public{        MyStruct storage newStruct = myStructs[structId];        newStruct.id = structId;        newStruct.flags[flagKeys] = true;    }//获取数据function  getStruct(        uint256 structId,        uint256 flagKeyspublic   viewreturns (uint256, bool) {        MyStruct storage myStruct = myStructs[structId];        bool keys = myStruct.flags[flagKeys];     return (myStruct.id, keys);    }//删除结构体,这里直接通过删除id来删除function   deleteStruct(uint256 structId)public{        MyStruct storage myStruct = myStructs[structId];        delete myStructs[structId];    }}
03
remix复现

部署完合约后,首先调用我们addStruct ,赋值1,2,第一个值会被记录,而第二个值则会进行bool值判断,默认没有传入值的时候是false,传入值后就变为true

调用getStruct方法查看具体值

DeFiVulnLabs靶场全系列详解(三十八)结构体不完全的删除导致数据残留可能数据泄露

例如我未传入2,3  所以bool为false

DeFiVulnLabs靶场全系列详解(三十八)结构体不完全的删除导致数据残留可能数据泄露

然后再调用deleStruct删除,这里直接delete结构体的下标的值

function   deleteStruct(uint256 structId) public{        MyStruct storage myStruct = myStructs[structId];        delete myStructs[structId];    }}

可以看到,并没有删除干净,按照预期应该第二位是bool值为false,而不是true,而第一个值可以看到uint256的值为0,是预期内的值,被正确删除了。

DeFiVulnLabs靶场全系列详解(三十八)结构体不完全的删除导致数据残留可能数据泄露

主要原因是因为flags的值是一个mapping,mapping在solidity是一种特殊的结构,delete 关键字只会重置结构体的基本字段,而不会删除结构体内部的映射。这意味着映射中的数据仍然会保留在存储中,导致数据残留。

04
如何修复该问题

需要先删除结构体里的值,然后再删除结构体才可以,这样就不会有数据残留了,注意看我用了三个delete函数

delete myStructs[structId].id;       重置id字段为默认值为0

delete myStruct.flags[i];        重置flag为默认值false

delete myStructs[structId];     再次确保整个结构体为被重置为默认值

function  deleteStruct(uint256 structId) public{        MyStruct storage myStruct = myStructs[structId];           delete myStructs[structId].id;            for (uint256 i = 0; i < 100; i++) {               delete myStruct.flags[i];         }               delete myStructs[structId];    }
DeFiVulnLabs靶场全系列详解(三十八)结构体不完全的删除导致数据残留可能数据泄露
05
感谢关注
个人语雀账号:https://www.yuque.com/iceqaq

原文始发于微信公众号(Ice ThirdSpace):DeFiVulnLabs靶场全系列详解(三十八)结构体不完全的删除导致数据残留可能数据泄露

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

发表评论

匿名网友 填写信息