Уязвимость в struct
Не довелось мне поработать со struct достаточно хорошо, поэтому следующий баг был для меня в новинку.
Рассмотрим просто контракт:
contract NameRegistrar {
bool public unlocked = false; // registrar locked, no name updates
struct NameRecord {
bytes32 name;
address mappedAddress;
}
mapping(address => NameRecord) public registeredNameRecord;
mapping(bytes32 => address) public resolve;
function register(bytes32 _name, address _mappedAddress) public {
NameRecord newRecord;
newRecord.name = _name;
newRecord.mappedAddress = _mappedAddress;
resolve[_name] = _mappedAddress;
registeredNameRecord[msg.sender] = newRecord;
require(unlocked);
}
}
Ничего странного не замечаете? Ошибок каких? Вроде бы их нет. Но есть один недочет.
Тут в контракте newRecord не инициализируется. Поэтому, когда в последующих строках мы устанавливаем значения:
newRecord.name = _name;
newRecord.mappedAddress = _mappedAddress;
они указывают на 0 и 1 слот в памяти, что приводит к установке значений в unlocked. И если мы передадим нужное значение в _name, то можно установить его, как true.
Так можно взломать этот контракт.
Вернее было бы оформить запись в struct так:
NameRecord memory newRecord = NameRecord({name: _name, mappedAddress: _mappedAddress});
Лично я не знал, что в этом случае структура может указывать на слоты памяти переменных. Поэтому важно инициализировать правильно.
Компилятор может указать вам на этот недочет, а в некоторых случая и остановить компиляцию контракта. Будьте внимательны со struct.
#struct #security
Post #474
197
- 🤯 2