Scannen von Live Ethereum-Verträgen auf nicht aktivierte Sendefehler. Teil 2

Fortsetzung des Artikels „Scannen von Live Ethereum-Verträgen auf den Fehler beim Deaktivieren des Sendens“. Teil 1 " .


Vor fast einem Jahr (während Ethereum in seiner "Frontier" -Veröffentlichung war) litt auch der beliebte EtherPot-Lotterievertrag [9] unter dem gleichen Fehler. Eine frühere Version von BTCRelay zeigte diesen Fehler ebenfalls [7] . Obwohl bei einem früheren Sicherheitsaudit eine Gefahr festgestellt wurde, wurde zunächst eine falsche Korrektur vorgenommen [8] .


Deaktiviert - Fehlererkennung bei Live-Blockhain senden


Wie häufig sind diese Fehler? Hören sie auf Warnungen? Werden Best Practices angewendet? Wir beantworten diese Fragen empirisch, indem wir die Daten aus der Ethereum-Blockkette sowie das auf etherscrape.com verfügbare Solidity-Code-Repository analysieren. Zu diesem Zweck entwickeln wir ein einfaches Programmanalysetool, das den Blockkettenvertrag überprüft und mithilfe von Heuristiken überprüft, ob eine der effektivsten Schutzmethoden verwendet wird. Listing 2 zeigt die erste Sicherheitstechnik, wie in der Ethereum-Dokumentation empfohlen, die den Rückgabewert von send überprüfen und eine Ausnahme auslösen sollte. Um die Verwendung dieser Methode zu erkennen, verwenden wir eine grobe Näherung: Wir prüfen nur, ob der Rückgabewert von send ignoriert wird oder nicht.

Listing 4 zeigt die zweite im UMD-Handbuch empfohlene Sicherheitstechnik, mit der direkt überprüft wird, ob der Callstack voll ist, indem eine Testnachricht gesendet wird. Um diese Technik zu entdecken, verwenden wir erneut eine grobe Näherung: Wir prüfen nur, ob zusätzlich zum Sendebefehl eine Nachricht gesendet wird.

Wenn keiner dieser heuristischen Indikatoren vorhanden ist, schließen wir, dass keine der Empfehlungen für bewährte Verfahren befolgt wird. Wir implementieren diese Heuristiken mithilfe eines einfachen Mustervergleichs mit kompiliertem EVM-Bytecode. Weitere Einzelheiten dazu finden Sie in Anhang [12] .


Wie viele Verträge sind anfällig?


Beginnen wir mit der Überprüfung der Heuristik im Etherscrape-Repository des Solidity-Quellcodes. Zum 20. März 2016 enthielt das Etherscrape-Relais 361 Solidity-Vertragsprogramme, von denen 56 eine Sendeerklärung enthielten. Von diesen Vertragsprogrammen gehen wir davon aus, dass die meisten (mindestens 36 von 56) keine der defensiven Programmiermethoden verwenden.

Selbst wenn der Vertrag keine der Schutztechnologien verwendet, kann er eine echte Sicherheitslücke aufweisen oder nicht. Wir haben Solidity-Verträge manuell überprüft, um die Sicherheitsanfälligkeit zu bestätigen. Für unsere Zwecke betrachten wir einen Vertrag als anfällig, wenn sich sein Status ändern kann, auch wenn der Sendebefehl nicht funktioniert (daher werden wir uns den anfälligen Code in Listing 5 ansehen). Wir haben bestätigt, dass die überwiegende Mehrheit der Sicherheitslücken vorhanden ist, 32 von 36 dieser Verträge.


Ebenso garantiert unsere Heuristik nicht die korrekte Anwendung der defensiven Programmierung. Nehmen wir zum Beispiel WeiFund, eine dezentrale Open-Source-Crowdfunding-DApp. Dieser Vertrag hat zwei Funktionen: Rückerstattung () und Auszahlung () , die unsere Heuristik austricksen. Das Folgende ist ein Auszug aus der Rückerstattung .


function refund(uint _campaignID, uint contributionID) public { ... receiver.send(donation.amountContributed); donation.refunded = true; ... if(c.config != address(0)) WeiFundConfig(c.config).refund(_campaignID, donation.contributor, donation.amountContributed); } 

In diesem Code wird eine Nachricht an WeiFundConfig (c.config) gesendet, um die Rückerstattungsmethode aufzurufen, jedoch nur unter bestimmten Bedingungen. Wenn c.config ein Nullwert ist, ist der Vertrag wirklich anfällig für einen Callstack-Angriff. Bei der Überprüfung * hat keines der Solidity-Programme, die unsere heuristischen Tests bestanden haben, die empfohlene beste Callstack-Testpraxis direkt angewendet. * *

Dann wenden wir uns den entworfenen Verträgen über die lebende Blockkette Ethereum zu. Wir haben uns das Bild vom 20. März 2016 angesehen (Zeitstempel: 1184243). Dieser Snapshot enthält insgesamt 13645 Blockketten, die anscheinend vom Solidity-Compiler generiert werden, von denen nur 1618 (11,8%) den Sendebefehl enthielten.

Von diesen scheint die überwiegende Mehrheit keine der defensiven Programmiertechniken zu verwenden.


Was ist mit dem rekursiven Rassenproblem in TheDAO? Der aufregendste Smart-Vertrag dieser Tage, TheDAO [11], weist einen völlig separaten Fehler auf, nämlich dass er nicht „sicher für die Wiederverwendung“ ist [13] . Dies ist eine andere (zusammenhängende, aber unterschiedliche) Art der unsicheren Programmierung, die auch bei früheren Sicherheitsüberprüfungen erwartet wurde [6] , aber nach wie vor ist es wahrscheinlich, dass viele Verträge heute unsicher sind. Zukünftige Arbeit bestand darin, ein Werkzeug zu entwickeln, das auch einen solchen Fehler erkennen konnte.


Wo ist alles schief gelaufen?


Wir erwarten nicht, dass die Programmierung auf intelligenten Verträgen zumindest vorerst völlig einfach ist. Es ist jedoch überraschend, dass diese besondere Form des Fehlers so weit verbreitet ist, obwohl sie in der Entwicklung des Ethereum-Ökosystems so lange beschrieben wurde.

In einem Bericht von 2015 [6] wurde Ethereum-Entwicklern diese Empfehlung gegeben: "

Derzeit reichen die in der Dokumentation vorgestellten Programmierbeispiele nicht aus, um bewährte Verfahren für das Schreiben sicherer Verträge und die Lösung des Gasmechanismusproblems zu verbreiten. C ++ - Einführungs-Tutorials werden häufig übersprungen
Fehlerprüfung auf Lesbarkeit, die zu zahlreichen Sicherheitsfehlern führte. Beispiele für Ethereum sollten die besten Gewohnheiten vermitteln. Empfehlung: Geben Sie noch mehr Beispiele für die sorgfältige Programmierung von Sicherheitsverträgen. "

Wir kennen nur eine offizielle Antwort auf diese Frage, nämlich eine Warnung in die zuvor erwähnte offizielle Solidity-Dokumentation [3] aufzunehmen, die unten wiederholt wird: "Bei Verwendung von send besteht eine gewisse Gefahr: Die Übertragung schlägt fehl, wenn die Tiefe des Aufrufstapels beträgt 1024 (dies kann immer vom Anrufer aufgerufen werden) und schlägt auch fehl, wenn dem Empfänger das Benzin ausgeht. Um eine sichere Übertragung zu gewährleisten, überprüfen Sie immer den Rückgabewert von send oder noch besser: Verwenden Sie das Muster in dem der Empfänger Geld abhebt. "


Wir glauben, dass diese Beobachtung nicht ausreicht, um das Problem zu dokumentieren. Es bietet nur eine unvollständige Minderung und beschreibt nur eine Version der Gefahr, was den Leser möglicherweise über seinen Grad irreführt.


  • Update:
    Die Unzulänglichkeit der Solidity-Dokumentation wurde auch von Peter Wesenes ausführlich veranschaulicht. [16]


Darüber hinaus scheint die Warnung oft übersehen zu werden. Wir sind daher der Ansicht, dass zusätzliche vorbeugende Maßnahmen erforderlich sind.



Wie kann Etherscrape helfen?


Wir glauben, dass die Verwendung statischer Analysetools, auch grober, wie die in diesem Beitrag beschriebenen, dazu beitragen kann, die Qualität intelligenter Verträge zu verbessern. Bei Etherscrape integrieren wir solche Analysetools in unseren öffentlichen Webdienst und fügen einen Link zur Seite des Tools hinzu wenn sie bereit sein wird. Dies erleichtert das Anzeigen des Smart-Vertragscodes, indem die Stellen hervorgehoben werden, an denen Fehler auftreten können. Wir gehen davon aus, dass Benutzer eines solchen intelligenten Vertrags (z. B. potenzielle Investoren von TheDAO oder seinen Angeboten) problemlos Tools wie die Überprüfung der geistigen Gesundheit verwenden können, bevor sie ihr Geld einzahlen. Selbst nicht technische Investoren können Entwickler zur Rechenschaft ziehen, wenn sie erklären, wie sie auf die im Code genannten Probleme reagiert haben.

Etherscrape hilft auch, indem es die öffentliche Blockkette analysiert und die Prävalenz dieses Fehlers kontrolliert. Dies kann beispielsweise bei der Entscheidung helfen, wie viel Geld für die Forschung und Entwicklung statischer Analysewerkzeuge bereitgestellt werden soll. Darüber hinaus können Compiler wie solc solche Analysen integrieren und den Programmierer warnen, wenn ein Fehler wahrscheinlich ist.


Empfohlene Lektüre



Source: https://habr.com/ru/post/de430684/


All Articles