Solidity и смарт-контракты Ethereum, урок #16 | Безопасность: Reentrancy, DoS

  Рет қаралды 6,919

Ilya Krukowski

Ilya Krukowski

Күн бұрын

Пікірлер: 66
@петрпетров-я9ц
@петрпетров-я9ц 2 жыл бұрын
Спасибо за подробные видео! Лучшее объяснения в рунете!!! Хотелось бы больше примеров по безопасности!!!!
@АверкинАнтон
@АверкинАнтон 2 жыл бұрын
Согласен! Понимание как обезопасить контракты пришло, но два примера маловато. Все равно спасибо за труды.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
@@АверкинАнтон Ну, не всё сразу. В видео про низкоуровневые вызовы пример тоже есть, потом ещё будет со временем
@usernamer519
@usernamer519 Жыл бұрын
Как всегда очень круто! Спасибо за такой ценный контент!!!
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
@Owner0
@Owner0 Жыл бұрын
самые лучше курсы по солидити , спасибо
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
@vladimireliseev7602
@vladimireliseev7602 Жыл бұрын
Спасибо за видео! Было очень интересно и позновательно!
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
@vd6952
@vd6952 Жыл бұрын
Огромное спасибо за видео. очень подробно и понятно!)
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
На здоровье
@Baby-Yoda
@Baby-Yoda 2 жыл бұрын
Отличные уроки, спасибо Вам.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Благодарю!
@404piano
@404piano 2 жыл бұрын
Спасибо большое за уроки!
@MrStrangewow
@MrStrangewow 2 жыл бұрын
А так, забавно, что к 16 уроку дошли 600 человек))) первый урок 15к просмотров. не умаляет титанического труда автора) Илья - лучший
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Это абсолютно нормально, так обычно и бывает
@MrStrangewow
@MrStrangewow 2 жыл бұрын
@@IlyaBodrovKrukowski Илья, пользуясь случаем хотелось бы задать вопрос. Изучаю сейчас JS + по вашим урокам Solidity. Если сильно поднатореть, реально ли сходу устроиться джуном solidity специалистом? на hh в основном ищут сеньоров или людей с коммерческим опытом работы.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
@@MrStrangewow Прецеденты есть: студент нашей школы, к примеру, нашёл недавно работу довольно быстро, хотя походил по множеству собеседований за несколько дней. Это реально, но не факт, что быстро получится всё-таки
@Работамузыкантомпоконтракту
@Работамузыкантомпоконтракту 4 ай бұрын
Илья, огромная благодарность за такой качественный контент 🙌 У меня вопрос по функции bid, в частности про знак += в выражении bidders[msg.sender] += msg.value; А точно ли должен быть += ? Ведь если юзер делает ставку повторно, то у него будет записано не просто более высокая ставка, которую он поставил, но и плюс сумма первой ставки. Или аукцион - это когда к существующей ставке добавляются новые ставки поверх?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 4 ай бұрын
На здоровье Можно как угодно, смотря, какие требования от этого контракта. Но если мы не суммируем ставки, то нужно сделать так, чтобы прошлую ставку можно было забрать (иначе деньги потеряются)
@MikhailKuklenkov
@MikhailKuklenkov Жыл бұрын
Доброго времени суток, Илья. Понравилось видео, понятно и лаконично. В качестве дискуссии хочу поинтересоваться каким образом злоумышленник может получить доступ к казне в случае DoS атаки, ведь результатом его действий, описанных в виде является блокировка выплаты рефундов участникам? В первом случае гешефт злоумышленника оказался более понятен.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
Никак Ну, причина тут та же, что и ddos обычных сайтов. Или взлом просто ради взлома, хотя казалось бы хакер не только не получает ничего, но и рискует быть деанонимизированным
@Receive_
@Receive_ 2 жыл бұрын
Спасибо за урок. Очень хочется больше объяснений по строке - (bool success,) = msg.sender.call{value: refundAmount}(""). Ранее такого синтаксиса не было. Что такое (bool success,) почему там запятая и что может быть после запятой? Почему в скобках? success - это переменная? Все тайна) Еще мучает вопрос: почему в атаке Dos не вернулись средства первому аккаунту? По логике должна была пройти оплата на первый адрес в списке?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
По поводу первого момента - я думаю, это разъяснится в следующем уроке, тк в целом там всё просто - круглые скобки позволяют распаковать значения, но второе нас тут не интересует. Что касается второго - транзакция не может пройти частично. Если она откатывается, то все изменения в ней не применяются. Поэтому и деньги не дойдут. Грубо говоря, не может быть так, что половине сотрудников зарплата пришла, а половине - нет.
@Receive_
@Receive_ 2 жыл бұрын
@@IlyaBodrovKrukowski как всегда отдельная благодарность за внимание. Я правильно понял, что пока цикл не закончится, ни одна транзакция не пройдёт?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
@@Receive_ Дело в том, что вызов ВСЕЙ функции - это 1 транзакция. То есть вот началась транзакция, и начали обрабатывать функцию. Пока функция не отработает вся, транзакция не завершится. Если же в функции идёт ошибка, то и транзакция полностью отменяется, со всеми изменениями, которые мы там делали. Поэтому по факту да, пока цикл не прокрутися полностью, то и транзакция не завершится и финальные изменения применены не будут. Значит если цикл обваливается в середине, то и изменения, сделанные раньше в этой же транзакции, отменятся
@googleadmin4749
@googleadmin4749 2 жыл бұрын
Способ защиты на 14:36 не совсем понял как будет работать за счет модификатора: Насколько я понял модификатор выполняется каждый раз перед вызовом функции, далее происходи вызов логики функции через _; деньги уходят атакующему, но далее на атакующем контракте повторно вызывается через receive() снова auction.refund() который вновь идет в модификатор и не проходит булеву проверку на этом обрывается выполнение модификатора и собственно всего тела функции refund() тем самым значение баланса атакующего не меняется, по этому достаточно атаковать повторно и деньги будут выведены хоть и без рекурсии. Что я не так понял? Проверка защиты на 15:08 не совсем корректна так как одновременно используются первый и второй способ, тут скорее сработал первый способ нежели второй через модификатор, если бы сработал модификатор, так как выполняется сначала coll и там сваливается в рекурсию которая прерывается булевой проверкой и так как до изменения баланса выполнение функции не дошло то запросить вывод можно еще раз. UP: Кажется я понял, рекурсия атаки через Reentrancy выполняется в одной транзакции, прежде вся рекурсия формирует повторные транзакции и только впоследствии они отправляются на выполнение, а так как у нас стоит проверка то даже первая транзакция не обрабатывается так как при исключении все откатывается назад.
@Logi_Crypto
@Logi_Crypto 2 жыл бұрын
Был бы очень благодарен если вы бы ответили. Зачем мы пишем "ReentrancyAuction auction;" на начале контракта Reentrancy attack. Спасибо
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Чтобы это был не просто адрес, а объект, на котором можно вызывать функции этого контракта напрямую. Сравните address auction - просто адрес ReentrancyAuction auction - не просто адрес, а привязка к контракту с возможностью простого вызова функций
@Logi_Crypto
@Logi_Crypto 2 жыл бұрын
@@IlyaBodrovKrukowski спасибо огромное!
@oleksii.shkulipa
@oleksii.shkulipa 2 жыл бұрын
Спасибо большое за ваши видео, здоровезный просто кладязь концентрата информации Можно вас попросить сделать так же в каком-то ролике фронт част на nextjs, на функциональный компонентах с использованием theGraph И можно так же сделать видео пожалуйста по ipfs, с практическим примером, где и как им пользоваться, желательно с фронтом тоже конечно Спасибо большое
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Не могу обещать, скажу честно. Есть определённый план, будем смотреть, как оно пойдёт. Спасибо за отзыв!
@synchronization666
@synchronization666 2 жыл бұрын
thank you
@tylerdurden3869
@tylerdurden3869 6 ай бұрын
Спасибо за урок! у меня есть вопрос по поводу Reentrancy атаки. Как так происходит, что функция, которая начала выполнятся не выполнила bidders[msg.sender] = 0; если эта строчка прописана в конце? У нас происходит блокировка одного потока? То есть мы отправили наши деньги хаккеру, но почему дальше функция не выполняет условие с применением 0? Тут какой-то особенный call stack вызовов? То есть если мы запрашиваем быстро новую функцию refund, то она попадает первая в очередь блокируя те функции, которые не закончили свое выполнение?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 6 ай бұрын
Ну, на словах сложно объяснить, но по факту да, он не выполняет сначала всё, а потом делает следующий заход, а как бы ставит первый вызов на паузу, и идёт на следующий заход, а потом один за другим эти вызовы завершает. Как матрёшка
@satoshisumoto1945
@satoshisumoto1945 2 жыл бұрын
1. Получается можно посмотреть код каждого смартконтракта в сети? Если да, то как это сделать? 2. В случае 1й атаки, в коде он делает а) расчет баланса б) выплату в) обнуление баланса, но почему когда доходит до выплаты то далее идет раскрутка логики контракта-аттакера а в базовом контракте до конца функции мы так и не добрались вообще? Разве там не должна быть хотя бы гонка между receive() атакера и 1м или 2м шагом пункта (в) контракта-аукциона? 3. Получается можно всегда вызывать любые смартконтракты кого угодно, никаких аналогов cors не существует? 4. Получается что и никаких примитивов авторизации тоже нет? вопрос не по теме: потоков в солидити тоже нет, я полагаю? А какие-то обходные маневры для использования внешних веб сервисов из солидити тоже отсутствуют до сих пор? Ну и наконец: а в чем вообще необходимость смартконтрактов? Все что наблюдаю - довольно ограниченный и убогий функционал который следуя SOLID принципу апроксимированному на всю эту архитектуру, вообще не должен быть в блокчейне. Разве не логичнее было бы сделать "смартконтракты" отдельно работающими программами на серверах, которые бы имели: весь набор фич любого языка включая работу с БД, мультитрединг и тд и заканчивая тем, что они бы имели высокую скорость и возможность горизонтального скалирования.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
1. Etherscan 2. Тут внимательнее посмотрите логику 3. Нет
@satoshisumoto1945
@satoshisumoto1945 2 жыл бұрын
​@@IlyaBodrovKrukowski по логике получается что в базовом контракте выполняется строка по переводу средств, после чего сразу включается логика второго контракта по приему средств которая в свою очередь заного вызывает функцию базового контракта по переводу средств. Но ведь рантайм базового контракта до конца еще не отработал после первого вызова, там остались еще 2 строки: require и обнуление баланса. Или в солидити за все про все отвечает лишь 1 поток рантайма который забыл что у него есть еще 2 строки и он перескакивает на второй контракт а потом снова на начало базового? А кстати как контракт работает если его вызвали одновременно несколько пользователей и предположим так вышло что все они попали к одному и тому-же майнеру который выделяет свои компьютерные ресурсы для работы контракта?: они в очереди ждут друг друга или создается несколько виртуальных машин где независимо запускается 1 и тот же контракт?
@nb-cy6cw
@nb-cy6cw 2 жыл бұрын
На 12 минуте видео урока вы показали пример защиты с занулением до того как пройдёт оплата Но есть вопрос, что делать, если мы занулили, а оплата не прошла успешно, например, не существующий кошелёк или ещё что-то ? Получается, что пользователь не сможет попробовать ещё раз сделать refund, так как у него уже 0 Если подумать, то лучше всего добавить в конце условие, что если оплата не прошла успешно, то надо вернуть в mapping истенное значение для refund
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Там можно просто добавлять такие кошельки в отдельный массив и с ними разбираться уже в ином режиме. Вариантов много
@nb-cy6cw
@nb-cy6cw 2 жыл бұрын
Спасибо
@googleadmin4749
@googleadmin4749 2 жыл бұрын
То ради чего стоило пройти весь путь до )
@stopfake4094
@stopfake4094 2 жыл бұрын
Добрый день))) спасибо за уроки))) Если можете объясните пожалуйста как в конце после закомментирования получились балансы user1 и user2.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Добрый! Такие вопросы лучше задавать в нашем чате (ссылка в описании)
@googleuser518
@googleuser518 2 жыл бұрын
когда делаем call, адрес который получает средства, не помечаем payable?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Нет, это не требуется
@WithoutNickname666
@WithoutNickname666 2 жыл бұрын
Спасибо за урок! А если в атаке DoS мы перенесем refundProgress++; в начало функции сразу после address bidder = allBidders[i]? Поможет ли это в защите?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
В принципе, да, но тогда там выйдет, что и легитимным пользователям могут какие-то деньги не дойти
@WithoutNickname666
@WithoutNickname666 2 жыл бұрын
@@IlyaBodrovKrukowski Долго думал, но так и не мог понять почему.. В чем причина?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
@@WithoutNickname666 ну там если мы сначала делаем инкремент, а потом переводим деньги, то получается, что если даже перевод не прошёл, в повторном заходе в цикл мы уже этот адрес не будем обрабатывать (тк инкремент-то сработал). Хотя, если честно, в конкретно этом примере всё это плюс-минус бесполезно: там если любой платёж не прошёл, то денег никто не получит по-любому и progress каждый раз будет 0. Но в контракте, с которого я это списывал, ситуация была сложнее и они делали выплаты не всем сразу, а как бы блоками
@white6006
@white6006 2 жыл бұрын
Интересно, спасибо. Также можно рассмотреть реальные скам-токены и разобрать типы эксплоитов. На реальном примере всегда интересно. Например в сети BSC: 0x145fc2dc6c54c9fed4ce01f96fe0de6992f6d703 или любой другой. Как правило, они копируются многократно и выходят под разными именами.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
хорошая мысль
@MrStrangewow
@MrStrangewow 2 жыл бұрын
поддерживаю идею. Илья, был бы благодарен за рассмотрение скам монеток(на бск или эфире), дабы в след булране была возможность их избежать
@white6006
@white6006 2 жыл бұрын
Если хочется получить просмотры и возможно подтолкнуть канал, есть предложение. Рассмотреть ситуацию с Луной-UST. Это тоже как живой пример, а не лабораторная работа. Немного популистский :) Возможно не в этот плей-лист, а просто на канал. Делать нужно быстро, пока вопрос актуальный.
@ingegov
@ingegov 2 жыл бұрын
Добрый, большое спасибо, было бы круто, если бы вы ответили работу со смарт-контрактами на других языках ( фронт) к примеру, клиент на питоне в рамках бота или веб/моб приложение на flutter это сильно бы помогло
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Возможно, когда-нибудь и до этого дойдут руки, но сказать сложно
@Valentine-xo3yb
@Valentine-xo3yb 2 жыл бұрын
Уроки очень качественные, спасибо. Хотел уточнить, и Reentrancy и DoS упираются в вызов .call(value:) функции? Т.е. если отправлять с контракта эфир с помощью функций send или transfer то в этом случае Reentrancy невозможен? И что на счет отправки ERC20 токенов, там можно не беспокоится о потенциальных Reentrancy при трансфере токена с контракта пользователю?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
Reentrancy в теории может быть везде, где есть вызов сторонних контрактов. Transfer/send - всё равно проблемы могут быть, просто эти функции имеют жёсткий лимит по газу (2300), но и в него тоже можно уместиться и сделать что-нибудь нехорошее. Поэтому желательно априори считать вызов сторонних каких-то контрактов небезопасным. Вообще-то, раньше transfer действительно считалась безопасной функцией, но только никто не учёл, что стоимости по газу могут меняться. Если раньше "втиснуться" в лимит 2300 особо было нельзя, то теперь вполне можно (стоимости упали). Поэтому надо быть всё равно аккуратным
@Valentine-xo3yb
@Valentine-xo3yb 2 жыл бұрын
@@IlyaBodrovKrukowski Спасибо за ответ. Поискал немного информации про недавние успешные Reentrancy атаки, и натолкнулся на хак Rari Fuse (форк compound). Был удивлен, что протокол который прошел несколько аудитов все равно оставался уязвим к такому простому взлому. Получается защита через noReentrancy модификатор защищает от повторного входа только в ту же самую функцию, но не защищает от возможности зайти в другую функцию этого же контракта.
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
@@Valentine-xo3yb Ну там да, ведь мы модификатор на 1 функцию вешаем, он её и проверяет
@Уважаемыйпользователь-ю9к
@Уважаемыйпользователь-ю9к Жыл бұрын
Здравствуйте! Попробовал сделать как у вас первую часть урока, но ничего не получилось. Повлялось только много ошибок в хардхат, потом добавил цикл try catch как в dos в тесты и заработало, только атака не удавалась, деньги не списывались. Потом убрали из кода солидити условие bool success и require и заработало все как надо, при условии что разница между отправленной суммой и той которую я хочу получить в ходе атаки должать быть в 20 раз, но не больше. Не могли бы вы рассказать с чем это связанно? Разрабы повысили безопасность смарт контрактов включив каки-то условия по дефолту или как? Можете перепроверить код, если не сложно или может вы тоже сталкивались с таким? Заранее спасибо
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski Жыл бұрын
Хм. Это должно работать как и раньше... Можно написать в наш чат (ссылка в описании) и сбросить код, народ глянет, что там и как
@SCEP9X
@SCEP9X 2 жыл бұрын
😼🤙
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
@Anonimus_13
@Anonimus_13 2 жыл бұрын
А вы просто для разнообразия сделали рефанд с помощью (bool success,) = msg.sender.call{value: refundAmount}("") вместо payable(msg.sender).transfer(refundAmount)?
@IlyaBodrovKrukowski
@IlyaBodrovKrukowski 2 жыл бұрын
call более гибкий, да и в целом чаще встречается. transfer хотели использовать для защиты от reentrancy но в целом теперь это ненадёжный метод.
Don’t Choose The Wrong Box 😱
00:41
Topper Guild
Рет қаралды 62 МЛН
Mom Hack for Cooking Solo with a Little One! 🍳👶
00:15
5-Minute Crafts HOUSE
Рет қаралды 23 МЛН
It’s all not real
00:15
V.A. show / Магика
Рет қаралды 20 МЛН
It works #beatbox #tiktok
00:34
BeatboxJCOP
Рет қаралды 41 МЛН
Квантовая Битва: Мир На Пороге Эры Без Секретов
25:03
Hardhat, Ethers.js, Rinkeby, Alchemy, Etherscan
30:56
Ilya Krukowski
Рет қаралды 5 М.
Don’t Choose The Wrong Box 😱
00:41
Topper Guild
Рет қаралды 62 МЛН