Wir haben gerade gesehen, wie ein kleines Schlupfloch zu einem finanziellen Verlust (unterschiedlicher Größenordnung) führt, ähnlich wie Smart Contracts, die über Solidity entwickelt wurden, anfällig für verschiedene bekannte und unbekannte Angriffe sind. Die Exploiter nutzen Bugs und Schlupflöcher, um in Smart Contracts einzudringen und diese für Angriffe zu manipulieren. Hier präsentieren wir eine umfassende Liste der Top 5 der am häufigsten auftretenden Fehler in der Solidity-Programmiersprache.
Bei QuillAudits folgen wir der adaptiven Methodik, um den Kern jedes Hacks zu erfassen und seine Erkenntnisse in zukünftige Smart Contracts umzusetzen, um potenzielle Bedrohungen zu vermeiden.
Fehler in der Solidity-Programmiersprache
1. Nicht markierter externer Anruf
Wir ziehen dieses Problem an erster Stelle, weil es eine der am häufigsten beobachteten Fallstricke von Solidity ist. Im Allgemeinen erfolgt das Senden von Ether an ein externes Konto über das Transfer() Funktion. Abgesehen davon sind die beiden am häufigsten verwendeten Funktionen, um einen externen Anruf zu tätigen; Anruf() und send (), hier hauptsächlich die Anruf() -Funktion wird von den Entwicklern ausgiebig verwendet, um vielseitige externe Anrufe durchzuführen.
Obwohl die Anruf() und send () Funktionen geben einen booleschen Wert zurück, der angibt, ob der Aufruf erfolgreich war oder nicht. Wenn also in diesem Fall eine der Funktionen Anruf() or send () Wenn die Aufgabe nicht ausgeführt wird, werden sie mit a . zurückgesetzt falsch Wenn der Entwickler den Rückgabewert nicht gegenprüft, würde dies zu einer Falle.
Die Sicherheitslücke
Betrachten Sie das folgende Beispiel:
Vertragslotto{
boolpublic ausgezahlt =false;
Adresse öffentlicher Gewinner;
uintpublic winAmount;
// … hier zusätzliche Funktionalität
Funktion sendToWinner()public{
erfordern(!ausgezahlt);
Gewinner.send (WinAmount);
ausgezahlt = wahr;
}
Funktion zurückziehenLeftOver()public{
erfordern (ausgezahlt);
msg.sender.send(diese.Balance);
}
}
In dem Lotto-ähnlichen Vertrag oben können wir beobachten, dass a Gewinner erhält Gewinnbetrag des Äthers, der ein wenig übrigbleibt, um von jedem externen Mittel abgezogen zu werden.
Hier besteht die Fallstricke für den Vertrag in Zeile [11], wobei a senden wird ohne Kreuzvalidierung der Antwort verwendet. Im obigen Beispiel ist a Gewinner deren Transaktion fehlschlägt (entweder durch Gasmangel oder wenn es sich um einen Vertrag handelt, der absichtlich die Fallback-Funktion einführt), autorisiert bezahltAus eingestellt werden auf was immer dies auch sein sollte. unabhängig davon, ob die Ether-Transaktion erfolgreich war oder nicht. In diesem Fall kann jeder Ausbeuter die Gewinner Gewinne über die via zurückziehenLeftOver Funktion.
Der Ansatz von QuillAudit
Unser internes Entwicklerteam behebt diesen Fehler mit Hilfe von [Transfer] Funktion statt [senden] Funktion, da [transfer] zurückgesetzt wird, wenn die externe Transaktion zurückgesetzt wird. Und wenn Sie [send] verwenden, überprüfen Sie immer den Rückgabewert.
Einer der robusten Ansätze, die wir verfolgen, ist die Verwendung eines [Entzugsmusters]. Hier isolieren wir die externe Sendefunktion logisch vom Rest der Codebasis und belasten den Endbenutzer durch potenziell fehlgeschlagene Transaktionen, da er derjenige ist, der die Rückzugsfunktion aufruft.
2. Wiedereinreise
Die Smart Contracts von Ethereum rufen und verwenden Codes von anderen externen Verträgen, und um dies durchzuführen, müssen die Verträge externe Anrufe senden. Diese externen Anrufe sind anfällig und anfällig für Angriffe, ein solcher Angriff fand kürzlich im Fall eines DAO-Hack statt.
Die Sicherheitslücke
Angreifer führen solche Angriffe durch, wenn ein Vertrag Ether an eine unbekannte Adresse sendet. In diesem Fall kann der Angreifer an einer externen Adresse einen Vertrag erstellen, der Schadcode in der Fallback-Funktion besitzt, und dieser Schadcode wird aufgerufen, wenn der Vertrag Ether an diese Adresse sendet.
Tatsache: Der Begriff „Reentrancy“ wurde von der Tatsache geprägt, dass wenn ein externer bösartiger Vertrag eine Funktion über den anfälligen Vertrag aufruft und dann der Code-Ausführungspfad „wieder eintritt“.
Betrachten Sie das folgende Beispiel: Es handelt sich um einen Ethereum-Tresor, der es Einlegern ermöglicht, nur 1 Ether pro Woche abzuheben.
Vertrag EtherStore {
uint256 öffentliches Abhebungslimit = 1 Äther;
Zuordnung(Adresse => uint256) public lastWithdrawTime;
Mapping(Adresse => uint256) öffentliche Salden;
Funktion depositFunds() extern zahlbar {
Salden[msg.sender] += msg.value;
}
Funktion abhebenFunds (uint256 _weiToWithdraw) public {
require(salden[msg.sender] >= _weiToWithdraw);
// die Auszahlung begrenzen
require(_weiToWithdraw <= Auszahlungslimit);
// Begrenzen Sie die Zeit, um sich zurückzuziehen
require(jetzt >= lastWithdrawTime[msg.sender] + 1 Wochen);
require(msg.sender.call.value(_weiToWithdraw)());
Guthaben[msg.sender] -= _weiToWithdraw;
lastWithdrawTime[msg.sender] = jetzt;
}
}
Im obigen Vertrag haben wir zwei öffentliche Funktionen, [depositFunds] und [withdrawFunds]. [depositFunds] wird verwendet, um das Guthaben des Absenders zu erhöhen, während [withdrawFunds] den abzuhebenden Betrag angibt. In diesem Fall ist es ein Erfolg, wenn der abzuhebende Betrag weniger als 1 Ether beträgt.
Die Falle liegt hier in Zeile [17], wo die Übertragung des Äthers stattfindet. Der Angreifer könnte einen böswilligen Vertrag mit der Vertragsadresse von [EtherStores] als einzigem Konstruktorparameter erstellen. Dies würde [etherStore] zu einer öffentlichen Variable machen und somit anfälliger für Angriffe.
Der Ansatz von QuilllAudit
Wir befolgen verschiedene Techniken, um potenzielle Sicherheitslücken beim Wiedereintritt in Smart Contracts zu vermeiden. Der allererste und bestmögliche Weg ist die Verwendung der eingebauten [Transfer]-Funktion beim Übertragen von Ether auf einen externen Vertrag.
Zweitens ist es wichtig sicherzustellen, dass alle logischen Änderungen in den Zustandsvariablen durchgeführt werden, bevor Ether aus dem Vertrag geschickt wird. Im Beispiel [EtherStore] sollten die Zeilen [18] und [19] vor Zeile [17] stehen.
Eine dritte Technik kann auch verwendet werden, um wiedereintretende Anrufe zu verhindern; durch die Einführung eines Mutex. Es ist eine Hinzufügung einer Zustandsvariablen, die den Vertrag während der Codeausführung sperrt.
3. Standardsichtbarkeiten
Es gibt Sichtbarkeitsspezifizierer für die Funktionen, die wir in Solidity verwenden, und sie geben vor, wie sie aufgerufen werden können. Es ist die Sichtbarkeit, die den Aufruf der Funktionen bestimmt; extern durch Nutzer, durch andere abgeleitete Verträge, nur intern oder nur extern. Schauen wir uns an, wie die fehlerhafte Verwendung von Sichtbarkeitsspezifizierern zu großen Sicherheitslücken in Smart Contracts führen kann.
Die Sicherheitslücke
Standardmäßig ist die Sichtbarkeit der Funktion [public], daher können die externen Benutzer die Funktionen ohne spezifische Sichtbarkeit aufrufen. Der Fehler tritt auf, wenn Entwickler vergessen, die Sichtbarkeit von Funktionen anzugeben, die privat sein sollten (oder im Vertrag selbst aufgerufen werden können). Beispielsweise;
Vertrag HashForEther {
Funktion zurückziehenWinnings() {
// Gewinner, wenn die letzten 8 Hex-Zeichen der Adresse 0 sind
erfordern (uint32 (msg.sender) == 0);
_sendWinnings();
}
Funktion _sendWinnings() {
msg.sender.transfer(dieses.Guthaben);
}
}
Der obige Vertrag ist ein einfaches Kopfgeldspiel zum Erraten von Adressen. Darin sehen wir, dass die Sichtbarkeit der Funktionen nicht angegeben ist, insbesondere ist die Funktion [ _sendWinnings] [public] (standardmäßig), daher kann diese über eine beliebige Adresse aufgerufen werden, um das Kopfgeld zu stehlen.
Der Ansatz von QuillAudit
Unser Inhouse-Team besteht aus erfahrenen Entwicklern, die immer den besten Audit-Praktiken folgen, hier sollte die Sichtbarkeit der Funktionen explizit angegeben werden, auch wenn diese öffentlich bleiben sollen, sollte es erwähnt werden.
4. Sicherstellung des Einsatzes von Konstruktoren
Im Allgemeinen werden Konstruktoren als spezielle Funktionen bezeichnet, die verwendet werden, um kritische und privilegierte Aufgaben während der Initialisierung der Verträge auszuführen. Vor Solidity [v0.4.22] hatten Konstruktoren denselben Namen wie der Vertrag, der sie enthielt. Betrachten Sie nun einen Fall, in dem der Vertragsname während der Entwicklungsphase geändert wird, der Konstruktorname jedoch gleich bleibt. Diese Lücke kann Angreifern auch einen einfachen Zugang zu Ihrem Smart Contract bieten.
Die Sicherheitslücke
Es kann schwerwiegende Folgen haben, wenn der Vertragsname geändert wird, der Name des Konstruktors jedoch unverändert bleibt. Beispielsweise:
VertragsinhaberWallet {
Adresse öffentlicher Eigentümer;
// Konstrukteur
Funktion ownerWallet(Adresse _owner) public {
Eigentümer = _Eigentümer;
}
// Zurückgreifen. Sammle Äther.
Funktion () zahlbar {}
Funktion zurückziehen() öffentlich {
require(msg.sender == Eigentümer);
msg.sender.transfer(dieses.Guthaben);
}
}
Im obigen Vertrag sehen wir, dass nur der Besitzer Ether über den Aufruf der Funktion [withdraw] abheben kann. Hier tritt die Schwachstelle auf, da der Konstruktor anders benannt ist als im Vertrag (der Anfangsbuchstabe ist anders!). Somit kann der Exploit die Funktion [ownerWallet] aufrufen und sich selbst als Eigentümer autorisieren und dann den gesamten vertraglichen Ether durch Aufrufen von [withdraw] zurückziehen.
Der Ansatz von QuillAudit
Wir erfüllen die Version [0.4.22] des Solidity-Compilers. Diese Version hat ein Schlüsselwort eingeführt; [constructor] erfordert, dass der Name der Funktion mit dem Vertragsnamen übereinstimmt.
5. Tx.Origin-Authentifizierung
Hier ist [Tx.Origin] die globale Variable von Solidity, sie enthält die Adresse des Kontos, das den Anruf oder die Transaktion ursprünglich ausgeführt hat. Diese Variable kann nicht zur Authentifizierung verwendet werden, da dies den Vertrag anfällig für Phishing-Angriffe macht.
Die Sicherheitslücke
Verträge, die Benutzer über die Variable [tx.origin] autorisieren, sind externen Angriffen ausgesetzt, die Benutzer dazu bringen, authentifizierte Aktionen für den fehlerhaften Vertrag auszuführen. Betrachten Sie das folgende Beispiel:
Phishing-Vertrag {
Adresse öffentlicher Eigentümer;
Konstruktor (Adresse _owner) {
Eigentümer = _Eigentümer;
}
function () extern zahlbar {} // Ether sammeln
Funktion zurückziehenAll(address _recipient) public {
erfordern (tx.origin == Eigentümer);
_recipient.transfer (dieses. Guthaben);
}
}
Hier in Zeile [11] autorisiert der Vertrag die Funktion [withdrawAll] mit Hilfe von [tx.origin].
Der Ansatz von QuillAudit
Wir vermeiden generell die Verwendung von [tx.origin] für die Autorisierung in Smart Contracts. Obwohl die Verwendung von [tx.origin] nicht streng verboten ist, gibt es einige spezifische Anwendungsfälle. Wir können [tx.origin] verwenden, um externen Verträgen den Aufruf des vorliegenden Vertrages zu verweigern, es kann mit [require] der Form [require(tx.origin == msg.sender)] ausgeführt werden. Es wird getan, um den Aufruf von Zwischenverträgen zu vermeiden, um den aktuellen Vertrag abzurufen, der den Vertrag auf normale codelose Adressen beschränkt.
Letzte Zusammenfassung
Wir haben die fünf häufigsten Fallstricke in der Solidity-Sprache umfassend behandelt. Bei der Entwicklung von Smart Contracts dürfen wir nicht vergessen, dass sie vom Design her unveränderlich sind, was bedeutet, dass es nach der Erstellung keine Möglichkeit gibt, den Quellcode zu patchen.
Dies stellt Entwickler vor eine große Herausforderung, die verfügbaren Sicherheitstest- und Überwachungstools vor der Bereitstellung zu nutzen.
Die Erkennung potenzieller bösartiger Bedrohungen der Smart Contracts und der Risiken, von denen einige oben erwähnt wurden, wird von unserem internen Team von Auditing-Experten auf einzigartige und robuste Weise durchgeführt. Wir bei QuillAudits setzen unser Bestes in die Sicherheitsforschung, um Ihren Vertrag mit allen Software-Sicherheitspraktiken auf dem neuesten Stand zu halten, um Ihren Vertrag sicher und geschützt zu halten.
Erreichen Sie QuillHash
Mit einer Branchenpräsenz von Jahren, QuillHasch hat weltweit Unternehmenslösungen geliefert. QuillHash mit einem Expertenteam ist ein führendes Blockchain-Entwicklungsunternehmen, das verschiedene Branchenlösungen einschließlich DeFi Enterprise anbietet. Wenn Sie Unterstützung bei der Prüfung intelligenter Verträge benötigen, wenden Sie sich bitte an unsere Experten hier!
Folgen Sie QuillHash für weitere Updates
Quelle: https://blog.quillhash.com/2021/06/04/top-5-common-errors-in-solidity-programming-language/
- 11
- Konto
- Vorteil
- Alle
- Prüfung
- Authentifizierung
- Genehmigung
- BESTE
- Blockchain
- Fehler
- Bugs
- rufen Sie uns an!
- Fälle
- Verursachen
- challenges
- Code
- gemeinsam
- Unternehmen
- Vertrag
- Verträge
- Strom
- DAO
- DeFi
- Design
- Entwickler:in / Unternehmen
- Entwickler
- Entwicklung
- Unternehmen
- Äther
- Astraleum
- Event
- Experten
- Revolution
- Vorname
- folgen
- unten stehende Formular
- Frei
- Funktion
- Zukunft
- Spiel
- GAS
- Global
- groß
- hacken
- hier
- Ultraschall
- HTTPS
- riesig
- Einschließlich
- Energiegewinnung
- IT
- Sprache
- führen
- führenden
- Line
- Liste
- Spiel
- Andere
- Eigentümer
- Patch
- Schnittmuster
- Phishing
- Phishing-Attacken
- verschreiben
- Gegenwart
- privat
- Programmierung
- Öffentlichkeit
- Ziehen
- Forschungsprojekte
- Antwort
- REST
- safe
- Sicherheitdienst
- Leistungen
- kompensieren
- Einfacher
- klein
- smart
- Smart-Vertrag
- Smart Contracts
- So
- Software
- solide
- Lösungen
- Bundesstaat
- Erfolg
- Testen
- Die Quelle
- Bedrohungen
- Zeit
- Top
- top 5
- Transaktion
- Transaktionen
- us
- Nutzer
- Wert
- Gewölbe
- Sichtbarkeit
- Sicherheitslücken
- Verwundbarkeit
- Verwundbar
- Woche
- WHO
- .
- Jahr