BNB Chain è una delle blockchain più popolari nel mondo Web3. Le sue tariffe ragionevoli, le transazioni veloci e il ricco ecosistema di progetti attirano un gran numero di utenti. Come con qualsiasi blockchain, gli sviluppatori di BNB Chain dovrebbero prima considerare i problemi di sicurezza durante il processo di sviluppo: perché qualsiasi perdita di fondi porterà a un indebolimento della fiducia degli utenti nel protocollo e nella piattaforma, e le vulnerabilità della sicurezza e gli attacchi degli hacker sono uno dei rischi maggiori. devono affrontare gli sviluppatori.

In questo articolo, forniamo dieci consigli pratici sulla sicurezza in modo che gli sviluppatori possano ridurre i rischi e sviluppare contratti intelligenti più sicuri su BNB Chain.

01 

╱Definizione ╱

I Replay Attack, noti anche come replay attack e replay attack, sono un tipo comune di attacco nell'ambiente blockchain. Nella sicurezza informatica, un "replay attack" è un tipo di attacco di rete in cui una trasmissione di dati valida viene ripetuta o ritardata in modo doloso o fraudolento.

Nel contesto Web3 e dei contratti intelligenti, ciò significa generalmente che un utente malintenzionato è in grado di ripetere una transazione o un'azione in uno smart contract senza il permesso dell'utente originale. Ciò può portare a varie forme di frode come la doppia spesa, ecc.

Questi attacchi possono avere gravi conseguenze per utenti e sviluppatori perché consentono agli aggressori di riutilizzare la stessa firma per ottenere accesso non autorizzato a tutti i fondi o altre risorse dello smart contract.

Per prevenire attacchi di tipo replay, gli sviluppatori devono progettare e implementare attentamente il proprio codice di contratto intelligente e seguire la verifica della firma nonché i migliori standard di sicurezza del settore.

02 

╱ Analisi del caso ╱

Il seguente frammento di codice rappresenta il processo di implementazione del trasferimento di un token sulla catena BNB. Il codice è vulnerabile agli attacchi di riproduzione, consentendo a un utente malintenzionato di riutilizzare la stessa firma.

Questa funzionalità è priva di protezione nonce o replay, consentendo a un utente malintenzionato di "riprodurre" un trasferimento firmato più volte. Un utente malintenzionato può intercettare una transazione firmata e inviarla nuovamente allo stesso contratto o a un altro contratto e il contratto la considererà comunque valida, quindi l'utente malintenzionato può sfruttare questa vulnerabilità per rubare risorse.

03 

╱ Metodi di miglioramento ╱

Aggiungi un nonce alla firma o utilizza variabili di mappatura per registrare la firma. Le soluzioni più specifiche varieranno a seconda del disegno del progetto.

01 

╱Definizione ╱

Un attacco di rientro si verifica quando un contratto dannoso richiama ripetutamente un contratto vulnerabile prima che la chiamata iniziale venga completata. In altre parole, un utente malintenzionato può "ingannare" un contratto vulnerabile facendogli credere di aver completato una transazione e di essere libero di passare a quella successiva, ma in realtà sta ancora eseguendo il codice dannoso dell'utente malintenzionato.

Ciò potrebbe far sì che un utente malintenzionato possa manipolare lo stato del contratto in modi inaspettati e potenzialmente ottenere fondi non autorizzati.

02 

╱ Analisi del caso ╱

Nello snippet di codice riportato di seguito, gli utenti possono prelevare fondi dal proprio conto chiamando la funzione di prelievo e specificando l'importo che desiderano prelevare. Tuttavia, poiché la funzione di ritiro non protegge dalle chiamate ricorsive alla funzione, è vulnerabile agli attacchi di rientro.

Un utente malintenzionato potrebbe sfruttare la vulnerabilità creando un contratto dannoso che richiama più volte la funzione di prelievo prima che il saldo venga effettivamente addebitato sul proprio conto. La funzione msg.sender.call invia fondi al contratto dannoso e l'aggressore utilizza la funzione receiver() del contratto dannoso per prelevare ripetutamente fondi prima che il suo saldo venga ridotto a zero, esaurendo così tutti i fondi del contratto della vittima.

03 

╱ Metodi di miglioramento ╱

Effettua aggiornamenti di stato prima di qualsiasi chiamata esterna.

Questo modello è chiamato modello "Check-Effects-Interact" ed è un modello di progettazione utilizzato per prevenire attacchi di rientro nei contratti intelligenti. Questo modello separa i cambiamenti di stato dalle chiamate esterne ad altri contratti controllando prima le precondizioni e quindi aggiornando lo stato prima di effettuare qualsiasi chiamata esterna. In questo modo, se una chiamata esterna innesca una richiamata che tenta di richiamare al contratto, ma lo stato è già stato aggiornato, si evitano altri effetti imprevisti.

Seguendo questo modello, gli sviluppatori possono garantire che i loro contratti siano più sicuri e meno suscettibili agli attacchi di rientro.

Un'altra possibile soluzione è utilizzare un modificatore per limitare più chiamate alla stessa funzione, proprio come ReentrancyGuard di OpenZeppelin.

01 

╱Definizione ╱

Gli oracoli possono aiutare i contratti intelligenti a recuperare informazioni dall’esterno della blockchain. Di solito il prezzo di un asset di scambio decentralizzato (DEX) è determinato dal prezzo estratto dall'oracolo dall'ultima transazione riuscita sul DEX.

Il problema però è che il prezzo può essere facilmente manipolato da chiunque, causando problemi con lo smart contract. Vediamo spesso casi di oracoli sui prezzi manipolati attraverso prestiti flash. Il motivo è che i prestiti flash consentono agli utenti di prendere in prestito enormi quantità di denaro senza garanzie purché ripaghino il prestito all’interno dello stesso blocco. Ciò rende facile per gli aggressori influenzare o addirittura manipolare i prezzi, traendo profitto da false liquidazioni, prestiti eccessivi o operazioni commerciali sleali.

02 

╱Analisi del caso╱

Di seguito è riportato uno snippet di codice vulnerabile agli attacchi di manipolazione degli oracoli.

Questo contratto consente agli utenti di scambiare il token A con il token B utilizzando il contratto di routing, ma si basa su un oracolo esterno (contratto Uniswap Pair) per ottenere riserve di token A e token B per calcolare il prezzo. Un utente malintenzionato è riuscito a manipolare le riserve del contratto Uniswap Pair nonché la funzione getAmountOut, provocando infine l'esecuzione dello swap a un prezzo irragionevole.

03 

╱ Metodi di miglioramento ╱

Per prevenire questo attacco, gli sviluppatori dovrebbero utilizzare una rete Oracle decentralizzata in grado di ottenere il prezzo medio ponderato per il volume (VWAP) o il prezzo medio ponderato per il tempo (TWAP) degli scambi centralizzati e decentralizzati sulla catena. In questo modo, i dati verranno raccolti da più fonti e in un ampio intervallo di tempo, rendendo il codice meno suscettibile ad attacchi e manipolazioni. È importante che gli sviluppatori siano in grado di rimuovere qualsiasi vettore di attacco che manipola gli oracoli dai contratti intelligenti per prevenire potenziali vulnerabilità.

01 

╱Definizione ╱

L’impostazione corretta della visibilità delle funzioni garantisce la sicurezza e l’integrità dei contratti intelligenti. L'utilizzo di impostazioni errate di visibilità delle funzioni può consentire a utenti non intenzionali di manipolare lo stato del contratto, causando problemi seri come il furto di fondi o il controllo della funzionalità del contratto.

Impostando la visibilità di una funzione su privata o interna, ti assicuri che gli sviluppatori abbiano accesso limitato a determinate funzioni e che solo il personale autorizzato possa accedervi. Le funzioni private possono essere richiamate solo dal contratto stesso, mentre le funzioni interne possono essere richiamate anche dal contratto in corso. Ciò consente agli sviluppatori di creare contratti più potenti e complessi mantenendo il controllo sull'accesso alle funzionalità.

02 

╱ Analisi del caso ╱

La funzione setAdmin() consente a chiunque di impostare qualsiasi indirizzo come amministratore del contratto. A seconda delle autorizzazioni concesse all'interno del contratto per la gestione degli indirizzi, ciò potrebbe far sì che lo sviluppatore perda il controllo del contratto stesso e addirittura provochi una perdita di fondi.

Impostando la visibilità della funzione su interno, alcune funzioni del contratto potrebbero consentire internamente a determinati utenti di essere impostati come amministratori.

03 

╱ Metodi di miglioramento ╱

I modificatori di accesso sono un'importante funzionalità di sicurezza che determina chi può accedere a funzioni o variabili specifiche in un contratto. Questi modificatori possono essere utilizzati per limitare la visibilità di determinate funzioni o variabili a ruoli o indirizzi specifici e impedire ad autori malintenzionati di ottenere accesso non autorizzato o manipolare lo stato del contratto.

Ad esempio, un contratto potrebbe avere una funzione che solo il proprietario del contratto può chiamare o una variabile a cui può accedere solo un insieme specifico di indirizzi.

L'accesso alla funzione setAdmin può essere limitato all'indirizzo del titolare del contratto modificando il modificatore di visibilità su esterno e impostando il modificatore di accesso su onlyOwner. Ciò impedirà a soggetti esterni malintenzionati di assumere il controllo di determinate funzioni privilegiate.

L'uso corretto della visibilità e dei modificatori restrittivi può rendere più semplice la gestione del contratto e ridurre gli attacchi comuni come la rientranza (un utente malintenzionato richiama ripetutamente una funzione per manipolare lo stato del contratto) o gli attacchi front-running (un utente malintenzionato monitora le transazioni in sospeso e manipola lo stato del contratto prima che sia legale). le transazioni vengono eseguite).

Utilizzando queste funzionalità in modo appropriato, gli sviluppatori possono migliorare la sicurezza e l'affidabilità dei propri contratti, ridurre il rischio di accesso non autorizzato e migliorare la qualità complessiva e la manutenibilità del proprio codice.

01 

╱Definizione ╱

Quando si decide se aggiornare un contratto in futuro, è importante considerare attentamente inizialmente la progettazione del contratto. L’aggiornabilità del contratto si riferisce alla proprietà secondo cui la logica di un contratto intelligente può essere modificata o aggiornata dopo essere stata implementata sulla blockchain. Sebbene l'aggiornabilità possa offrire molti vantaggi (come la correzione di bug, il miglioramento dell'efficienza o l'aggiunta di nuove funzionalità), introduce anche alcuni rischi. Gli aggiornamenti del contratto possono introdurre nuove vulnerabilità, aumentare la complessità del contratto o causare conseguenze indesiderate.

L'aggiornabilità dei contratti solleva anche problemi di fiducia perché gli amministratori degli agenti possono aggiornare i contratti senza il consenso della comunità. Gli sviluppatori devono valutare attentamente i vantaggi e gli svantaggi dell'aggiornabilità e determinare se l'introduzione di contratti aggiornabili è veramente necessaria per il loro progetto. In alcuni casi, è più sicuro concepire un contratto immutabile fin dall’inizio piuttosto che fare affidamento sulla possibilità di modificarlo in seguito.

02 

╱ Metodi di miglioramento ╱

Quando si tratta di aggiornabilità del contratto, ci sono diverse pratiche importanti da seguire. Innanzitutto, non modificare la libreria proxy. La libreria del contratto Proxy è estremamente complessa, soprattutto in termini di gestione dello storage e meccanismi di aggiornamento. Anche piccoli errori possono influenzare notevolmente il funzionamento del proxy e dei contratti logici. In effetti, molti degli errori critici relativi ai proxy scoperti durante l'audit sono stati causati da modifiche inappropriate alla libreria proxy.

Un altro aspetto chiave dell'aggiornabilità del contratto è l'inclusione di un "gap" di stoccaggio nel contratto base. I contratti logici devono includere un gap di archiviazione nel codice contratto per tenere conto delle nuove variabili che potrebbero essere introdotte durante la distribuzione di nuove implementazioni logiche. Dopo aver aggiunto nuove variabili di stato, aggiornare la dimensione del "gap" diventa ancora più importante. Questa pratica garantisce che i futuri aggiornamenti procederanno senza intoppi e senza problemi.

Infine, è necessario evitare di utilizzare selfdestruct() o di eseguire delegatecall()/call() su contratti non attendibili. Un utente malintenzionato può sfruttare queste funzioni per sovvertire l'implementazione della logica o eseguire una logica personalizzata. Per evitare ciò, è importante convalidare l'input dell'utente! Non consentire ai contratti di eseguire delegatecall()/call() su contratti non attendibili. Inoltre, non è consigliabile utilizzare delegatecall() nei contratti logici, poiché la gestione del layout di archiviazione su più contratti può essere difficile. Seguendo queste pratiche, gli sviluppatori possono ridurre al minimo le vulnerabilità e i rischi negli aggiornamenti del contratto.

01 

╱Definizione ╱

Il front-running è sempre stato un problema ostinato e difficile da risolvere, in cui gli utenti sono in grado di trarre profitto dal ritardo tra l’invio di una transazione e la sua conferma sulla blockchain. Questo ritardo è causato da mempool.

mempool è un'area di archiviazione temporanea utilizzata per archiviare transazioni non confermate che sono state trasmesse alla rete. Tutti i nodi della rete mantengono un mempool, consentendo a chiunque di vedere le transazioni in sospeso e potenzialmente intercettarle e trarne profitto. Mempool offre inoltre ai minatori l'opportunità di riorganizzare le transazioni per massimizzare i propri profitti, creando ciò che è noto come valore estraibile del minatore (o massimo) (MEV).

02 

╱ Analisi del caso ╱

Di seguito è riportato un esempio di una funzionalità di offerta d'asta incline al front-running.

Questa funzionalità consente agli utenti di fare offerte nelle aste, ma potrebbe essere soggetta ad attacchi front-running. Supponiamo che un utente malintenzionato monitori la blockchain e veda che un altro utente ha presentato un'offerta alta. L'utente malintenzionato può presentare rapidamente un'offerta più alta e ricevere la priorità, vincendo infine l'asta.

Nella versione successiva, gli utenti inviano prezzi di offerta sconosciuti e queste offerte vengono archiviate in una mappatura. Gli importi delle offerte vengono crittografati fino alla fine del periodo di offerta.

03 

╱ Metodi di miglioramento ╱

Alla fine del periodo di offerta, gli utenti possono rivelare la propria offerta inviando l'importo dell'offerta originale e un valore segreto. Il contratto verifica che l'importo dell'offerta e l'hash segreto corrispondano all'offerta segreta memorizzata, garantendo che l'offerta sia stata presentata prima della fine del periodo dell'asta. Se l'offerta è superiore all'offerta massima corrente, diventa la nuova offerta massima. Questa funzionalità mitiga gli attacchi front-running mascherando gli importi delle offerte fino alla fine del periodo dell'asta.

Il front-running e il MEV sono diventati una delle principali preoccupazioni nella comunità blockchain e sono state proposte varie soluzioni, come le transazioni e i Fair Ordering Services (FSS), per affrontare questi problemi. Le transazioni possono aiutare a prevenire il front-running nascondendo i dettagli della transazione ad altri utenti finché la transazione non viene eseguita sulla blockchain. D’altro canto, FSS può ridurre l’impatto del front-running e del MEV attraverso l’ordinazione sicura di transazioni off-chain.

Avere un piano di risposta chiaro e completo è fondamentale per gestire gli incidenti di sicurezza di emergenza. Il piano dovrebbe essere regolarmente rivisto, aggiornato e testato per verificarne l’efficacia. Quando si verifica un’emergenza di sicurezza, il tempo è essenziale. Il piano dovrebbe pertanto essere personalizzato in anticipo e includere fasi operative dettagliate per l’identificazione, il controllo e la mitigazione.

Il piano dovrebbe essere messo in atto in modo efficace per tenere informate tutte le parti interessate. Allo stesso tempo, anche il backup regolare dei dati è importante per prevenire la perdita di dati. Il piano deve delineare il processo di ripristino per ripristinare dati e sistemi allo stato precedente. I membri del team dovrebbero ricevere una formazione sistematica sul piano per garantire che tutti comprendano i propri ruoli e responsabilità.

Un piano di risposta ben preparato potrebbe non essere in grado di risolvere il problema, ma può ridurre al minimo l’impatto dell’incidente e mantenere la fiducia con gli utenti e le parti interessate.

I controlli regolari del codice sono fondamentali per mantenere la sicurezza della tua applicazione. Lavorare con un revisore professionista specializzato nella sicurezza dei contratti intelligenti è un passo importante nel processo di sviluppo. I revisori esamineranno il codice per individuare eventuali vulnerabilità e forniranno raccomandazioni per migliorare la sicurezza generale.

Stabilire le priorità e risolvere i problemi identificati e mantenere una comunicazione aperta con i revisori sono fondamentali per migliorare la sicurezza.

Oltre a ciò, anche la comunicazione con i revisori è fondamentale. Gli auditor possono spiegare in dettaglio i problemi e le vulnerabilità scoperti e fornire indicazioni e aiuto pratico su come risolvere la vulnerabilità. Collaborando con agenzie/personale di audit professionale, la sicurezza verrà "portata al livello successivo".

Per gli sviluppatori della catena BNB, condurre audit regolari è parte integrante di qualsiasi strategia di sicurezza globale. L'identificazione e la risoluzione proattiva delle vulnerabilità nel codice possono ridurre al minimo il rischio di violazioni della sicurezza.

L'utilizzo di un programma di ricompensa è un modo efficace per incentivare gli hacker white hat nella comunità a segnalare vulnerabilità di sicurezza nel codice di un progetto. Fornendo incentivi come token o altri premi, qualsiasi progetto può incoraggiare persone esperte a rivedere il codice e segnalare eventuali problemi riscontrati.

È importante avere un programma di bug bounty chiaro e trasparente. Il piano deve includere: quali tipi di vulnerabilità scoperte possono beneficiare di premi, come valutare il valore di queste vulnerabilità, ecc. Allo stesso tempo, includere una terza parte rispettabile in un programma bug bounty può aiutare a garantire il regolare funzionamento del programma e l’equa distribuzione dei premi.

Allo stesso tempo, è importante avere un “gruppo di cacciatori di taglie” diversificato. Diversi hacker white hat hanno diverse aree di competenza e possono concentrarsi sulla ricerca di problemi che altri potrebbero non notare.

Infine, una volta segnalate le vulnerabilità, è necessario agire in modo rapido ed efficace per risolverle. I programmi Bounty possono essere uno strumento efficace per identificare le vulnerabilità, ma hanno senso solo se il team di sviluppo risolve effettivamente il problema.

Educare gli utenti Web3 sulla sicurezza è un passo fondamentale nella costruzione di un ecosistema sicuro. Garantire la sicurezza dei clienti aiuta a garantire la sicurezza della piattaforma. Gli utenti dovrebbero essere istruiti sulle migliori pratiche per proteggere i propri account e le informazioni sensibili.

La parte più importante è imparare come evitare le truffe di phishing.

I truffatori di phishing inducono gli utenti a rivelare le proprie chiavi private o password fingendo di essere un sito Web o un servizio legittimo. CertiK consiglia agli utenti di ricontrollare sempre qualsiasi URL di posta elettronica, origine, ecc. del sito Web utilizzato quando si ricevono informazioni e di non inserire mai chiavi private o password su siti Web non attendibili.

E un'altra parte importante è avere password sicure e complesse. CertiK consiglia agli utenti di utilizzare password univoche e complesse per ciascun account ed evitare di riutilizzare le password su servizi diversi. Inoltre, le password devono essere archiviate in modo sicuro utilizzando un gestore di password o un altro meccanismo di archiviazione sicuro.

Infine, la protezione delle chiavi private è estremamente importante. La chiave privata equivale alla password dell'utente e dovrebbe essere garantita l'impossibilità di accesso da parte di altri in qualsiasi momento. Gli utenti dovrebbero evitare di condividere le proprie chiavi private con chiunque e conservarle in un luogo sicuro.

Riassumere

Gli sviluppatori che creano contratti intelligenti e dApp su BNB Chain devono adottare un approccio di sicurezza globale per proteggere i fondi e le risorse dei propri utenti. Ciò che è più importante è essere proattivi piuttosto che reattivi quando si affrontano violazioni della sicurezza; disporre di un piano in atto quando o anche prima che si verifichi una violazione e fornire un'adeguata formazione sulla sicurezza a tutti gli utenti e le parti interessate interessate. Combinando tutte le misure di cui sopra, puoi aiutare i progetti a ridurre significativamente il rischio di violazioni della sicurezza e attacchi di hacker.