Ethereum intelligens szerződés biztonsági ajánlások

blog 1NewsDevelopersEnterpriseBlockchain ExplainedEvents and ConferencesPressHírlevelek

Iratkozzon fel hírlevelünkre.

Email cím

Tiszteletben tartjuk a magánéletét

HomeBlogBlockchain fejlesztés

Ethereum intelligens szerződés biztonsági ajánlások

A külső hívások kezelésétől kezdve az elkötelezettségi rendszerekig itt találunk 10+ intelligens szerződéses biztonsági mintát, amelyeket az Ethereumra építve kell követni. – ConsenSys, 2020. július 10., 2020. július 10.

Ethereum intelligens szerződés biztonsági ajánlások

Amint azt az intelligens szerződéses biztonsági gondolkodásmódban bemutattuk, az éber Ethereum fejlesztő mindig öt alapelvet tart szem előtt:

  • Készüljön fel a kudarcra
  • Óvatosan indítsa el
  • Tartsa egyszerűnek a szerződéseket
  • Maradj naprakész
  • Legyen tisztában az EVM sajátosságaival

Ebben a bejegyzésben elmélyülünk az EVM sajátosságaiban, és végigvezetünk egy listát azokról a mintákról, amelyeket be kell tartanod, ha bármilyen intelligens szerződéses rendszert fejlesztesz az Ethereumon. Ez a darab elsősorban az Ethereum középhaladóinak szól. Ha még mindig a feltárás korai szakaszában jár, nézze meg a ConsenSys Academy igény szerinti blockchain fejlesztői programját. 

Oké, merüljünk be.

Külső hívások

Vigyázzon, ha külső hívásokat indít

A nem megbízható intelligens szerződésekre történő felhívás számos váratlan kockázatot vagy hibát okozhat. A külső hívások rosszindulatú kódokat hajthatnak végre az adott szerződésben vagy bármely más szerződésben, amely attól függ. Ezért kezeljen minden külső hívást potenciális biztonsági kockázatként. Ha nem lehetséges, vagy nem kívánatos a külső hívások eltávolítása, használja a szakasz további részében található ajánlásokat a veszély minimalizálása érdekében.

Megbízhatatlan szerződések megjelölése

Külső szerződésekkel való interakció során nevezze meg a változókat, módszereket és szerződéses interfészeket úgy, hogy világossá váljon, hogy a velük való interakció potenciálisan nem biztonságos. Ez vonatkozik a saját funkcióira, amelyek külső szerződéseket hívnak.

// rossz Bank.withdraw (100); // Nem világos, hogy a makeWithdrawal (uint amount) megbízható vagy nem megbízható függvény-e {// Nem világos, hogy ez a függvény potenciálisan nem biztonságos. Bank.withdraw (összeg); } // jó UntrustedBank.withdraw (100); // nem megbízható külső hívás TrustedBank.withdraw (100); // külső, de megbízható banki szerződés, amelyet az XYZ Corp függvény karbantart a makeUntrustedWithdrawal (uint összeg) {UntrustedBank.withdraw (összeg); } Kód nyelve: PHP (php)

Kerülje az állapotváltozásokat külső hívások után

Függetlenül attól, hogy nyers hívásokat (a someAddress.call () formában) vagy szerződéses hívásokat (az ExternalContract.someMethod () formában) használ, tegyük fel, hogy rosszindulatú kód futtatható. Még akkor is, ha az ExternalContract nem rosszindulatú, a rosszindulatú kód futtatható bármely általa meghívott szerződéssel.

Az egyik különös veszély, hogy a rosszindulatú kód eltérítheti a vezérlési folyamatot, ami az újbóli belépés miatt sebezhetőséghez vezet. (Lát Visszatérés a probléma teljesebb megvitatásához).

Ha nem megbízható külső szerződésre hív, kerülje az állapotváltozásokat a hívás után. Ezt a mintát néha a ellenőrzések-hatások-interakciók mintája.

Lát SWC-107

Ne használja a transfer () vagy a send ().

.továbbítsa () és.küldje () pontosan 2300 gázt továbbítson a címzettnek. Ennek a keménykódolt gázdíjnak a célja a megelőzés volt reentrancia sebezhetőségei, de ennek csak abban a feltételezésben van értelme, hogy a gázköltségek állandóak. EIP 1884, amely az isztambuli keményvilla része volt, megemelte a SLOAD művelet gázköltségét. Ez azt okozta, hogy a szerződés tartalék funkciója több mint 2300 gázba került. Javasoljuk, hogy hagyja abba a.transfer () és.send () használatát, ehelyett használja a.call ().

// rossz szerződés Vulnerable {function cancel (uint256 összeg) external {// Ez 2300 gázt továbbít, ami nem biztos, hogy elég, ha a címzett // szerződés és a gázköltségek változnak. msg.sender.transfer (összeg); }} // jó szerződés Fix {függvény visszavonás (uint256 összeg) külső {// Ez továbbítja az összes rendelkezésre álló gázt. Feltétlenül ellenőrizze a visszatérési értéket! (bool siker,) = msg.sender.call.value (összeg) (""); megkövetelik (siker, "Az átvitel nem sikerült."); }} Kód nyelve: JavaScript (javascript)

Ne feledje, hogy a. Call () nem tesz semmit az újbóli belépési támadások enyhítésére, ezért más óvintézkedéseket kell tenni. A visszatérési támadások megelőzéséhez használja a ellenőrzések-hatások-interakciók mintája.

Kezelje a külső hívások hibáit

A Solidity alacsony szintű hívási módszereket kínál, amelyek a nyers címeken működnek: address.call (), address.callcode (), address.delegatecall () és address.send (). Ezek az alacsony szintű módszerek soha nem vetnek ki kivételt, de hamis értéket adnak vissza, ha a hívás kivétellel találkozik. Másrészt a szerződéses hívások (pl. ExternalContract.doSomething ()) automatikusan továbbítják a dobást (például az ExternalContract.doSomething () akkor is dob, ha a doSomething () dobja).

Ha alacsony szintű hívási módszerek mellett dönt, győződjön meg arról, hogy a visszahívási érték ellenőrzésével kezeli a hívás sikertelenségének lehetőségét..

// rossz néhányAddress.send (55); someAddress.call.value (55) (""); // ez kétszeresen veszélyes, mivel továbbítja az összes megmaradt gázt, és nem ellenőrzi az eredményt someAddress.call.value (100) (bytes4 (sha3 ("letét()"))); // ha a betét kivételt vet, a nyers hívás () csak hamis értéket ad vissza, és a tranzakció NEM kerül visszaállításra // jó (bool siker,) = someAddress.call.value (55) (""); if (! siker) {// hibakód kezelése} ExternalContract (someAddress) .deposit.value (100) (); Kód nyelve: JavaScript (javascript)

Lát SWC-104

Kedvező húzás a külső hívásokhoz

A külső hívások véletlenül vagy szándékosan kudarcot vallhatnak. Az ilyen hibák okozta kár minimalizálása érdekében gyakran jobb, ha minden külső hívást elkülönítünk a saját tranzakciójukból, amelyet a hívás fogadója kezdeményezhet. Ez különösen releváns a fizetéseknél, ahol jobb, ha hagyjuk, hogy a felhasználók pénzfelvételt végezzenek, ahelyett, hogy automatikusan pénzhez juttatnák őket. (Ez is csökkenti az esélyét problémák a gáz határértékével.) Kerülje a több étertranszfer kombinálását egyetlen tranzakcióban.

// rossz szerződés aukciója {address higherBidder; uint maximumBid; függvény ajánlat () fizetendő {igényel (msg.value >= legmagasabbBid); if (legnagyobbBidder! = cím (0)) {(bool siker,) = legnagyobbBidder.call.value (legnagyobbBid) (""); megkövetelik (siker); // ha ez a hívás folyamatosan kudarcot vall, senki más nem tud licitálni} maximumBidder = msg.sender; maximumBid = msg.value; }} // jó szerződéses aukció {address maximumBidder; uint maximumBid; leképezés (cím => uint) visszatérítések; függvény ajánlat () fizetendő külső {igényel (msg.value >= legmagasabbBid); if (legmagasabb ajánlattevő! = cím (0)) {visszatéríti [legmagasabb ajánlatot] + = legmagasabb licit; // rögzítsük a visszatérítést, amelyet ez a felhasználó igényelhet} maximumBidder = msg.sender; maximumBid = msg.value; } függvény visszavonása (visszatérítés) visszatérítés () külső {uint visszatérítés = visszatérítés [msg.sender]; visszatérítések [msg.sender] = 0; (bool siker,) = msg.sender.call.value (visszatérítés) (""); megkövetelik (siker); }} Kód nyelve: JavaScript (javascript)

Lát SWC-128

Ne hívjon megbízhatatlan kódot

A delegatecall függvény más szerződésekből hívja a függvényeket, mintha a hívó szerződéshez tartoznának. Így a megbízott megváltoztathatja a hívó cím állapotát. Ez bizonytalan lehet. Az alábbi példa megmutatja, hogy a delegatall hívás felhasználása a szerződés megsemmisüléséhez és egyensúlyának elvesztéséhez vezethet.

contract Destructor {function doWork () external {selfdestruct (0); }} szerződéses munkavállaló {function doWork (_internalWorker cím) public {// nem biztonságos _internalWorker.delegatecall (bytes4 (keccak256 ("dolgozni()"))); }} Kód nyelve: JavaScript (javascript)

Ha a Worker.doWork () meghívást kap a telepített Destructor szerződés címével argumentumként, akkor a Worker szerződés önpusztít. – Csak megbízható szerződésekre ruházhatja a végrehajtást, és – soha ne a felhasználó által megadott címre.

Figyelem

Ne feltételezzük, hogy a szerződések nulla egyenleggel jönnek létre. A támadó étert küldhet a szerződés címére, mielőtt létrejön. A szerződések nem feltételezhetik, hogy kezdeti állapota nulla egyenleget tartalmaz. Lát 61. szám további részletekért.

Lát SWC-112

Ne feledje, hogy az éter erőszakkal elküldhető egy számlára

Vigyázzon egy olyan invariáns kódolására, amely szigorúan ellenőrzi a szerződés egyensúlyát.

A támadó erőszakkal küldhet étert bármely fiókra. Ezt nem lehet megakadályozni (még egy visszaállítást () végrehajtó tartalék funkcióval sem).

A támadó ezt megteheti úgy, hogy létrehoz egy szerződést, finanszírozza azt 1 wei-vel és meghívja az önmegsemmisítést (áldozatcím). Nincs kód meghívva az áldozatAddressben, ezért nem akadályozható meg. Ez igaz a blokk jutalomra is, amelyet a bányász címére küldenek, amely bármilyen tetszőleges cím lehet.

Továbbá, mivel a szerződés címei előre kiszámíthatók, az étert el lehet küldeni egy címre a szerződés telepítése előtt.

Lát SWC-132

Ne feledje, hogy az on-chain adatok nyilvánosak

Sok alkalmazás megköveteli, hogy a benyújtott adatok bizonyos idõpontig privátak legyenek a mûködéshez. Játékok (pl. Láncos kőzetpapír olló) és aukciós mechanizmusok (pl. Zárt licit Vickrey aukciók) a példák két fő kategóriája. Ha olyan alkalmazást épít, ahol az adatvédelem kérdés, ügyeljen arra, hogy ne követelje a felhasználókat az információk túl korai közzétételéről. A legjobb stratégia a használata kötelezettségvállalási rendszerek külön fázisokkal: először kösse be az értékek kivonatát, majd egy későbbi szakaszban fedje fel az értékeket.

Példák:

  • A kőzetpapír ollókban mindkét játékostól előbb követelje meg a tervezett mozdulat kivonatát, majd mindkét játékostól a mozdulat beküldését; ha a beküldött lépés nem felel meg a hashnak, dobja ki.
  • Egy aukción megkövetelheti a játékosoktól, hogy az első fázisban adják meg az ajánlati értékük kivonatát (az ajánlati értéküknél nagyobb befizetéssel együtt), majd a második szakaszban nyújtsák be aukciós ajánlatuk értékét..
  • Egy véletlenszám-generátortól függő alkalmazás kifejlesztésekor a sorrendnek mindig (1) a játékosoknak kell beküldeniük a mozdulatokat, (2) véletlenszerűen generált számokra, (3) a játékosoknak fizetniük kell. Sokan aktívan kutatják a véletlenszám-generátorokat; A kategória jelenlegi legjobb megoldásai közé tartoznak a Bitcoin blokkfejlécek (a következővel ellenőrizve: http://btcrelay.org), a kivonat-elkötelezettség-felfedés sémák (azaz az egyik fél generál egy számot, közzéteszi hashját, hogy “elkötelezze magát” az érték mellett, majd később feltárja az értéket), és RANDAO. Mivel az Ethereum egy determinisztikus protokoll, a protokollon belül egyetlen változót sem használhat kiszámíthatatlan véletlenszámként. Ne feledje, hogy a bányászok bizonyos mértékben ellenőrzik a block.blockhash () értéket*.

Vigyázzon azzal a lehetőséggel, hogy egyes résztvevők „offline állapotba kerülhetnek” és nem térnek vissza

Ne tegye függővé a visszatérítési vagy igénylési folyamatokat attól, hogy egy adott fél egy adott műveletet hajtson végre, anélkül, hogy más módon kimenne az alapokat. Például egy kő-papír-olló játékban az egyik gyakori hiba az, hogy addig nem fizetnek ki, amíg mindkét játékos el nem adja a mozdulatait; egy rosszindulatú játékos azonban úgy “gyászolhatja” a másikat, hogy soha nem nyújtja be a mozdulatát – sőt, ha egy játékos látja a másik játékos feltárt mozdulatát, és megállapítja, hogy elvesztette, akkor egyáltalán nincs oka a saját lépésének benyújtására. Ez a kérdés az állami csatornarendezéssel összefüggésben is felmerülhet. Ha az ilyen helyzetek problémát jelentenek, (1) lehetőséget nyújt a nem részt vevő résztvevők kijátszására, esetleg határidőn keresztül, és (2) fontolja meg egy további gazdasági ösztönző hozzáadását a résztvevők számára, hogy információkat nyújtsanak be minden olyan helyzetben, amelyben vannak. állítólag.

Óvakodjon a negatívabb előjelű egész szám tagadásától

A szilárdság számos típust biztosít aláírt egész számokkal való együttműködéshez. A legtöbb programozási nyelvhez hasonlóan a Solidityben is egy N bitű előjelű egész szám -2 ^ (N-1) és 2 ^ (N-1) -1 értékeket jelenthet. Ez azt jelenti, hogy nincs pozitív megfelelője a MIN_INT-nek. A tagadás úgy valósul meg, hogy megtalálja a szám kettőjének kiegészítését, tehát a legnegatívabb szám tagadását ugyanannyit eredményez. Ez a Solidity összes aláírt egész típusú típusára igaz (int8, int16,…, int256).

szerződés Negáció {function negate8 (int8 _i) public pure hozamok (int8) {return -_i; } function negate16 (int16 _i) public pure hozamok (int16) {return -_i; } int8 public a = negate8 (-128); // -128 int16 public b = negate16 (-128); // 128 int16 public c = negate16 (-32768); // -32768} Kód nyelve: PHP (php)

Ennek egyik módja, ha ellenőrizzük a változó értékét a tagadás előtt, és dobjuk, ha az megegyezik a MIN_INT értékkel. Egy másik lehetőség annak biztosítása, hogy a legnagyobb negatív számot soha ne érjük el nagyobb kapacitású típus használatával (pl. Int32 helyett int16).

Hasonló probléma az int típusokkal akkor fordul elő, ha a MIN_INT-et megszorozzuk vagy elosztjuk -1-gyel.

Biztonságos a blokklánc-kódod? 

Reméljük, hogy ezek az ajánlások hasznosak voltak. Ha Ön és csapata készül az indításra, vagy akár a fejlesztés életciklusának kezdetén van szükségünk, és intelligens szerződéseket kell ellenőrizni, kérjük, forduljon bizalommal a ConsenSys Diligence biztonsági mérnökeinkhez. Segítünk Önnek Ethereum alkalmazásainak 100% -os bizalommal történő elindításában és karbantartásában. 

Foglaljon biztonsági ellenőrzést

Foglaljon egy napos áttekintést a blockchain biztonsági szakértőink csapatától. Foglaljon ma Önöknek SecuritySmart szerződésekHírlevélFeliratkozás hírlevelünkre a legfrissebb Ethereum hírekről, vállalati megoldásokról, fejlesztői erőforrásokról és egyebekről. E-mail címExkluzív tartalomHogyan készítsünk sikeres blokklánc terméketWebinárium

Hogyan készítsünk sikeres blokklánc terméket

Hogyan állítsunk be és futtassunk Ethereum csomópontotWebinárium

Hogyan állítsunk be és futtassunk Ethereum csomópontot

Hogyan készítsünk saját Ethereum API-tWebinárium

Hogyan készítsünk saját Ethereum API-t

Hogyan hozhatunk létre közösségi tokentWebinárium

Hogyan hozzunk létre közösségi tokent

Biztonsági eszközök használata az intelligens szerződés-fejlesztésbenWebinárium

Biztonsági eszközök használata az intelligens szerződés-fejlesztésben

A pénzügyi eszközök digitális eszközei és a DeFi jövőjeWebinárium

A pénzügyek jövője: digitális eszközök és DeFi

Mike Owergreen Administrator
Sorry! The Author has not filled his profile.
follow me
Like this post? Please share to your friends:
Adblock
detector
map