Μόλις είδαμε πώς ένα μικρό κενό οδηγεί σε οικονομική απώλεια (διαφορετικού μεγέθους), με παρόμοιο τρόπο τα έξυπνα συμβόλαια που αναπτύχθηκαν μέσω της Solidity είναι επιρρεπή σε διάφορες γνωστές και άγνωστες επιθέσεις. Οι εκμεταλλευτές εκμεταλλεύονται τα σφάλματα και τα κενά για να ρίξουν μια ματιά σε έξυπνα συμβόλαια και να τα χειριστούν για να πραγματοποιήσουν επιθέσεις. Εδώ παρουσιάζουμε μια ολοκληρωμένη λίστα με τα 5 κορυφαία σφάλματα που απαντώνται συνήθως στη γλώσσα προγραμματισμού Solidity.
Στο QuillAudits ακολουθούμε την προσαρμοστική μεθοδολογία για να πάρουμε το επίκεντρο κάθε hack και να εφαρμόσουμε τις γνώσεις του σε μελλοντικά έξυπνα συμβόλαια για να αποφύγουμε οποιαδήποτε πιθανή απειλή.
Σφάλματα στη γλώσσα προγραμματισμού σταθερότητας
1. Μη επιλεγμένη εξωτερική κλήση
Αντιμετωπίζουμε αυτό το ζήτημα καταρχάς επειδή είναι μια από τις πιο συχνά παρατηρούμενες παγίδες Στερεότητας. Γενικά, η αποστολή αιθέρα σε οποιονδήποτε εξωτερικό λογαριασμό πραγματοποιείται μέσω του ΜΕΤΑΦΟΡΑ() λειτουργία. Εκτός από αυτό, οι δύο πιο ευρέως χρησιμοποιούμενες λειτουργίες για την πραγματοποίηση εξωτερικής κλήσης είναι: κλήση(), να αποστολή (), εδώ κυρίως το κλήση() Η λειτουργία χρησιμοποιείται εκτενώς για την εκτέλεση ευέλικτων εξωτερικών κλήσεων από τους προγραμματιστές.
Αν και το κλήση() και αποστολή () Οι συναρτήσεις επιστρέφουν μια δυαδική τιμή που καθορίζει εάν η κλήση ήταν επιτυχής ή όχι. Έτσι, στην περίπτωση αυτή, εάν υπάρχει κάποια από τις λειτουργίες κλήση() or αποστολή () αποτυγχάνει να εκτελέσει την εργασία, θα επιστρέψουν με ένα ψευδής Ως εκ τούτου, εάν ο προγραμματιστής δεν ελέγξει ξανά την τιμή επιστροφής, θα γίνει παγίδα.
Το θέμα ευπάθειας
Εξετάστε το παρακάτω παράδειγμα:
σύμβαση Λότο {
boolpublic payedOut = false;
απευθυνθείτε στο δημόσιο νικητή ·
uintpublic winAmount;
//… επιπλέον λειτουργικότητα εδώ
λειτουργία sendToWinner () δημόσια {
απαιτούν (! payedOut);
win.send (winAmount);
payedOut = true;
}
Λειτουργία απόσυρσηςLeftOver () δημόσια {
απαιτούν (payedOut)
msg.sender.send (this.balance);
}
}
Στην παραπάνω σύμβαση Lotto, μπορούμε να παρατηρήσουμε ότι α νικητής λαμβάνει winAmount αιθέρα αφήνοντας λίγο εναπομείνασμα για απομάκρυνση από οποιονδήποτε εξωτερικό παράγοντα.
Εδώ, η παγίδα για τη σύμβαση υπάρχει στη γραμμή [11], όπου a στείλετε χρησιμοποιείται χωρίς διασταυρούμενη επικύρωση της απόκρισης. Στο παραπάνω παράδειγμα, α νικητής του οποίου η συναλλαγή αποτυγχάνει (είτε λόγω έλλειψης φυσικού αερίου ή εάν πρόκειται για σύμβαση που ρίχνει σκόπιμα στη λειτουργία εναλλαγής), εξουσιοδοτεί πληρώθηκε να ρυθμιστεί σε αληθής ανεξάρτητα από το εάν η συναλλαγή αιθέρα ήταν επιτυχής ή όχι. Σε αυτήν την περίπτωση, κάθε εκμεταλλευτής μπορεί να αποσύρει το νικητής κέρδη μέσω του απόσυρσηLeftOver λειτουργία.
Προσέγγιση του QuillAudit
Η εσωτερική ομάδα προγραμματιστών μας αντιμετωπίζει αυτό το σφάλμα με τη χρήση του [ΜΕΤΑΦΟΡΑ] λειτουργία αντί για [στείλετε] λειτουργία, καθώς η [μεταφορά] θα επανέλθει εάν η εξωτερική συναλλαγή επανέλθει. Και αν χρησιμοποιείτε [αποστολή], ελέγχετε πάντα την τιμή επιστροφής.
Μία από τις ισχυρές προσεγγίσεις που ακολουθούμε είναι η χρήση ενός [μοτίβου απόσυρσης]. Εδώ, απομονώσαμε λογικά τη λειτουργία εξωτερικής αποστολής από την υπόλοιπη βάση κώδικα και τοποθετούμε την πίεση των δυνητικά αποτυχημένων συναλλαγών στον τελικό χρήστη, καθώς είναι αυτός που καλεί τη λειτουργία ανάληψης.
2. Επανεισδοχή
Οι έξυπνες συμβάσεις Ethereum καλούν και χρησιμοποιούν κωδικούς από άλλα εξωτερικά συμβόλαια, και για τη διεξαγωγή αυτού, τα συμβόλαια απαιτούνται για την υποβολή εξωτερικών κλήσεων. Αυτές οι εξωτερικές κλήσεις είναι ευάλωτες και επιρρεπείς σε επιθέσεις, μια τέτοια επίθεση έλαβε χώρα πρόσφατα στην περίπτωση του DAO hack.
Το θέμα ευπάθειας
Οι επιτιθέμενοι πραγματοποιούν τέτοιες επιθέσεις όταν ένα συμβόλαιο στέλνει αιθέρα σε άγνωστη διεύθυνση. Σε αυτήν την περίπτωση, ο εισβολέας μπορεί να δημιουργήσει ένα συμβόλαιο σε μια εξωτερική διεύθυνση που διαθέτει κακόβουλο κώδικα στη λειτουργία εναλλακτικού και αυτός ο κακόβουλος κώδικας θα καλείται όταν το συμβόλαιο στέλνει αιθέρα σε αυτήν τη διεύθυνση.
Γεγονός: Ο όρος «Επανεκκίνηση» επινοήθηκε από το γεγονός ότι όταν ένα εξωτερικό κακόβουλο συμβόλαιο καλεί μια συνάρτηση πάνω από το ευάλωτο συμβόλαιο και στη συνέχεια η διαδρομή εκτέλεσης κώδικα «εισέρχεται ξανά».
Εξετάστε το παρακάτω παράδειγμα, είναι ένα θησαυροφυλάκιο Ethereum που επιτρέπει στους καταθέτες να αποσύρουν μόνο 1 αιθέρα την εβδομάδα.
συμβόλαιο EtherStore {
uint256 δημόσια απόσυρσηLimit = 1 αιθέρας;
χαρτογράφηση (διεύθυνση => uint256) public lastWithdrawTime;
χαρτογράφηση (διεύθυνση => uint256) δημόσια υπόλοιπα.
συνάρτηση κατάθεσηςFunds () εξωτερικό πληρωτέο {
υπόλοιπα [msg.sender] + = msg.value;
}
Λειτουργία απόσυρσηςFunds (uint256 _weiToWithdraw) δημόσια {
απαιτείται (υπόλοιπα [msg.sender]> = _weiToWithdraw);
// περιορίστε την ανάληψη
απαιτούν (_weiToWithdraw <= pengeluaranLimit);
// περιορίστε τον χρόνο που επιτρέπεται να κάνετε ανάληψη
απαιτείται (τώρα> = lastWithdrawTime [msg.sender] + 1 εβδομάδες);
απαιτείται (msg.sender.call.value (_weiToWithdraw) ());
υπόλοιπα [msg.sender] - = _weiToWithdraw;
lastWithdrawTime [msg.sender] = τώρα;
}
}
Στο παραπάνω συμβόλαιο, έχουμε δύο δημόσιες λειτουργίες, [depositFunds] και [drawFunds]. Το [depositFunds] χρησιμοποιείται για την αύξηση του υπολοίπου του αποστολέα, ενώ το [drawFunds] καθορίζει το ποσό που θα αναληφθεί. Σε αυτήν την περίπτωση, θα είναι επιτυχία εάν το προς ανάληψη ποσό είναι μικρότερο από 1 αιθέρα.
Η παγίδα εδώ βρίσκεται στη γραμμή [17] όπου πραγματοποιείται η μεταφορά αιθέρα. Ο εισβολέας θα μπορούσε να δημιουργήσει ένα κακόβουλο συμβόλαιο με τη διεύθυνση συμβολαίου του [EtherStores] ως τη μόνη παράμετρο κατασκευαστή. Αυτό θα έκανε το [etherStore] μια δημόσια μεταβλητή, επομένως πιο επιρρεπείς σε επίθεση.
Προσέγγιση του QuilllAudit
Ακολουθούμε διάφορες τεχνικές για την αποφυγή πιθανών τρωτών σημείων επανεισόδου στα έξυπνα συμβόλαια. Ο πρώτος και καλύτερος τρόπος είναι η χρήση της ενσωματωμένης λειτουργίας [μεταφοράς] κατά τη μεταφορά αιθέρα σε οποιοδήποτε εξωτερικό συμβόλαιο.
Δεύτερον, είναι σημαντικό να διασφαλιστεί ότι όλες οι λογικές αλλαγές στις μεταβλητές κατάστασης πρέπει να γίνουν πριν από την αποστολή αιθέρα από τη σύμβαση. Στο παράδειγμα [EtherStore], οι γραμμές [18] και [19] πρέπει να τοποθετηθούν πριν από τη γραμμή [17].
Μια τρίτη τεχνική μπορεί επίσης να χρησιμοποιηθεί για την αποτροπή επανειλημμένων κλήσεων. μέσω της εισαγωγής ενός mutex. Είναι μια προσθήκη μιας μεταβλητής κατάστασης που θα κλειδώσει τη σύμβαση κατά την εκτέλεση κώδικα.
3. Προεπιλεγμένες ορατότητες
Υπάρχουν προσδιοριστές ορατότητας για τις λειτουργίες που χρησιμοποιούμε στο Solidity και καθορίζουν τον τρόπο με τον οποίο μπορούν να κληθούν. Είναι η ορατότητα που καθορίζει την κλήση των συναρτήσεων. εξωτερικά από χρήστες, με άλλα παράγωγα συμβόλαια, μόνο εσωτερικά ή μόνο εξωτερικά. Ας δούμε πώς η λανθασμένη χρήση των προσδιοριστών ορατότητας μπορεί να προκαλέσει τεράστια ευπάθεια στις έξυπνες συμβάσεις.
Το θέμα ευπάθειας
Από προεπιλογή, η ορατότητα της συνάρτησης είναι [δημόσια], επομένως οι εξωτερικοί χρήστες μπορούν να καλούν τις συναρτήσεις χωρίς συγκεκριμένη ορατότητα. Το σφάλμα προκύπτει όταν οι προγραμματιστές ξεχνούν να καθορίσουν την ορατότητα σε λειτουργίες που θα πρέπει να είναι ιδιωτικές (ή μπορούν να κληθούν εντός της ίδιας της σύμβασης). Για παράδειγμα;
σύμβαση HashForEther {
Λειτουργία απόσυρσης Winnings () {
// Νικητής εάν οι τελευταίοι 8 δεκαεξαδικοί χαρακτήρες της διεύθυνσης είναι 0
απαιτείται (uint32 (msg.sender) == 0);
_sendWinnings ();
}
συνάρτηση _sendWinnings () {
msg.sender.transfer (this.balance);
}
}
Το παραπάνω συμβόλαιο είναι ένα απλό παιχνίδι γενναιοδωρίας. Σε αυτό, μπορούμε να δούμε ότι η ορατότητα των συναρτήσεων δεν έχει καθοριστεί, ιδιαίτερα η συνάρτηση [_sendWinnings] είναι [δημόσια] (από προεπιλογή), επομένως αυτό μπορεί να κληθεί μέσω οποιασδήποτε διεύθυνσης για να κλέψει το bounty.
Προσέγγιση του QuillAudit
Η εσωτερική μας ομάδα αποτελείται από έμπειρους προγραμματιστές που ακολουθούν πάντα τις βέλτιστες πρακτικές ελέγχου, εδώ η ορατότητα των λειτουργιών πρέπει να προσδιορίζεται ρητά, ακόμη και αν πρόκειται να διατηρηθούν δημόσια, πρέπει να αναφερθεί.
4. Διασφάλιση της χρήσης κατασκευαστών
Γενικά, οι κατασκευαστές καλούνται ειδικές λειτουργίες που χρησιμοποιούνται για την εκτέλεση κρίσιμων και προνομιακών εργασιών κατά την αρχικοποίηση των συμβάσεων. Πριν από τη Σταθερότητα [v0.4.22], οι κατασκευαστές κρατούσαν το ίδιο όνομα που χρησιμοποιήθηκε από τη σύμβαση που τους περιείχε. Τώρα, σκεφτείτε μια περίπτωση όπου το όνομα του συμβολαίου αλλάξει κατά τη φάση ανάπτυξης, αλλά το όνομα του κατασκευαστή παραμένει το ίδιο, αυτό το κενό μπορεί επίσης να προσφέρει στους εισβολείς μια εύκολη είσοδο στο έξυπνο συμβόλαιό σας.
Το θέμα ευπάθειας
Μπορεί να οδηγήσει σε σοβαρές συνέπειες εάν το όνομα της σύμβασης τροποποιηθεί, αλλά το όνομα του κατασκευαστή είναι αμετάβλητο. Για παράδειγμα:
Ιδιοκτήτης συμβολαίουWallet {
διεύθυνση δημόσιου ιδιοκτήτη ·
// κατασκευαστής
function ownerWallet (διεύθυνση _owner) δημόσιο {
ιδιοκτήτης = _owner;
}
// Εφεδρική Συλλέξτε αιθέρα.
συνάρτηση () πληρωτέα {}
απόσυρση λειτουργίας () δημόσια {
απαιτείται (msg.sender == ιδιοκτήτης);
msg.sender.transfer (this.balance);
}
}
Στην παραπάνω σύμβαση, μπορούμε να δούμε ότι μόνο ο κάτοχος μπορεί να αποσύρει αιθέρα κάνοντας κλήση στη λειτουργία [απόσυρση]. Εδώ, η ευπάθεια εμφανίζεται καθώς ο κατασκευαστής ονομάζεται διαφορετικός από τη σύμβαση (το πρώτο γράμμα είναι διαφορετικό!). Έτσι, ο εκμεταλλευτής μπορεί να καλέσει τη λειτουργία [ownerWallet] και να εξουσιοδοτηθεί ως ιδιοκτήτης, και στη συνέχεια να αποσύρει όλο τον αιθέρα στη σύμβαση καλώντας [απόσυρση].
Προσέγγιση του QuillAudit
Συμμορφωνόμαστε με την έκδοση [0.4.22] του μεταγλωττιστή Στερεότητας. Αυτή η έκδοση εισήγαγε μια λέξη-κλειδί. [κατασκευαστής] που απαιτεί το όνομα της συνάρτησης να ταιριάζει με το όνομα της σύμβασης.
5. Έλεγχος ταυτότητας Tx.Origin
Εδώ, το [Tx.Origin] είναι η παγκόσμια μεταβλητή της Solidity, περιέχει τη διεύθυνση του λογαριασμού που αρχικά εκτέλεσε την κλήση ή τη συναλλαγή. Αυτή η μεταβλητή δεν μπορεί να χρησιμοποιηθεί για έλεγχο ταυτότητας, καθώς κάτι τέτοιο καθιστά τη σύμβαση ευάλωτη σε επιθέσεις ηλεκτρονικού "ψαρέματος".
Το θέμα ευπάθειας
Τα συμβόλαια που εξουσιοδοτούν τους χρήστες μέσω της μεταβλητής [tx.origin] εκτίθενται σε εξωτερικές επιθέσεις που οδηγούν τους χρήστες να εκτελούν επαληθευμένες ενέργειες στο εσφαλμένο συμβόλαιο. Εξετάστε το παρακάτω παράδειγμα:
σύμβαση Phishable {
διεύθυνση δημόσιου ιδιοκτήτη ·
κατασκευαστής (διεύθυνση _owner) {
ιδιοκτήτης = _owner;
}
συνάρτηση () εξωτερικά πληρωτέα {} // συλλογή αιθέρα
Λειτουργία απόσυρσης Όλα (διεύθυνση _recipient) δημόσια {
απαιτείται (tx.origin == ιδιοκτήτης);
_recipient.transfer (this.balance);
}
}
Εδώ στη γραμμή [11], η σύμβαση εξουσιοδοτεί τη λειτουργία [drawAll] με τη βοήθεια του [tx.origin].
Προσέγγιση του QuillAudit
Γενικά αποφεύγουμε τη χρήση του [tx.origin] για εξουσιοδότηση σε έξυπνες συμβάσεις. Αν και η χρήση του [tx.origin] δεν απαγορεύεται αυστηρά, έχει ορισμένες συγκεκριμένες περιπτώσεις χρήσης. Μπορούμε να χρησιμοποιήσουμε το [tx.origin] για να αρνηθούμε εξωτερικές συμβάσεις να καλέσουν το παρόν συμβόλαιο, μπορεί να εκτελεστεί με [απαιτείται] της φόρμας [απαιτείται (tx.origin == msg.sender)]. Αυτό γίνεται για να αποφευχθεί η κλήση των ενδιάμεσων συμβάσεων για την κλήση της τρέχουσας σύμβασης που περιορίζει τη σύμβαση σε κανονικές διευθύνσεις χωρίς κωδικό.
Τελική περιτύλιξη
Έχουμε καλύψει συνολικά τις πέντε κοινές παγίδες στη γλώσσα Solidity. Κατά την ανάπτυξη έξυπνων συμβολαίων, δεν πρέπει να ξεχνάμε ότι είναι αμετάβλητα από το σχεδιασμό, πράγμα που σημαίνει ότι μόλις τα δημιουργήσουμε, δεν υπάρχει τρόπος να διορθώσετε τον πηγαίο κώδικα.
Αυτό αποτελεί μεγάλη πρόκληση για τους προγραμματιστές να επωφεληθούν από τα διαθέσιμα εργαλεία ελέγχου και ελέγχου ασφαλείας πριν από την ανάπτυξη.
Ανακαλύπτοντας πιθανές κακόβουλες απειλές για τα έξυπνα συμβόλαια, και τους κινδύνους μερικών από τους οποίους αναφέραμε παραπάνω, εκτελούνται με έναν πολύ μοναδικό και ισχυρό τρόπο από την εσωτερική μας ομάδα ειδικών ελέγχου. Εμείς στην QuillAudits καταβάλλουμε κάθε δυνατή προσπάθεια στην έρευνα ασφάλειας για να ενημερώνουμε το συμβόλαιό σας με όλες τις πρακτικές ασφάλειας λογισμικού για να διατηρήσουμε το συμβόλαιό σας ασφαλές.
Προσεγγίστε το QuillHash
Με βιομηχανική παρουσία ετών, QuillHash έχει παράσχει επιχειρηματικές λύσεις σε όλο τον κόσμο. Η QuillHash με μια ομάδα εμπειρογνωμόνων είναι μια κορυφαία εταιρεία ανάπτυξης blockchain που παρέχει διάφορες βιομηχανικές λύσεις, συμπεριλαμβανομένης της εταιρείας DeFi, Εάν χρειάζεστε βοήθεια στον έλεγχο έξυπνων συμβάσεων, μη διστάσετε να επικοινωνήσετε με τους ειδικούς μας εδώ!
Ακολουθήστε το QuillHash για περισσότερες ενημερώσεις
Πηγή: https://blog.quillhash.com/2021/06/04/top-5-common-errors-in-solidity-programming-language/
- 11
- Λογαριασμός
- Πλεονέκτημα
- Όλα
- έλεγχος
- Πιστοποίηση
- εξουσιοδότηση
- ΚΑΛΎΤΕΡΟΣ
- blockchain
- Έντομο
- σφάλματα
- κλήση
- περιπτώσεις
- Αιτία
- πρόκληση
- κωδικός
- Κοινός
- εταίρα
- σύμβαση
- συμβάσεις
- Ρεύμα
- DAO
- Defi
- Υπηρεσίες
- Εργολάβος
- προγραμματιστές
- Ανάπτυξη
- Εταιρεία
- Αιθέρας
- ethereum
- Συμβάν
- εμπειρογνώμονες
- οικονομικός
- Όνομα
- ακολουθήστε
- μορφή
- Δωρεάν
- λειτουργία
- μελλοντικός
- παιχνίδι
- GAS
- Παγκόσμιο
- εξαιρετική
- σιδηροπρίονο
- εδώ
- Πως
- HTTPS
- τεράστιος
- Συμπεριλαμβανομένου
- βιομηχανία
- IT
- Γλώσσα
- οδηγήσει
- που οδηγεί
- γραμμή
- Λίστα
- Ταίριασμα
- ΑΛΛΑ
- ιδιοκτήτης
- Patch
- πρότυπο
- Phishing
- επιθέσεις ηλεκτρονικού ψαρέματος
- συνταγογραφήσει
- παρόν
- ιδιωτικός
- Προγραμματισμός
- δημόσιο
- τραβώντας
- έρευνα
- απάντησης
- ΠΕΡΙΦΕΡΕΙΑ
- ένα ασφαλές
- ασφάλεια
- Υπηρεσίες
- σειρά
- Απλούς
- small
- έξυπνος
- έξυπνη σύμβαση
- Έξυπνα συμβόλαια
- So
- λογισμικό
- στερεότητα
- Λύσεις
- Κατάσταση
- επιτυχία
- Δοκιμές
- Η Πηγη
- απειλές
- ώρα
- κορυφή
- 5 κορυφή
- συναλλαγή
- Συναλλαγές
- us
- Χρήστες
- αξία
- Θόλος
- ορατότητα
- Θέματα ευπάθειας
- ευπάθεια
- Ευάλωτες
- εβδομάδα
- Ο ΟΠΟΊΟΣ
- εντός
- χρόνια