原文标题:《Aggirare il livello zero: perché la sicurezza isolata non è sicurezza》
Autore: Krzysztof Urbański, membro del team L2BEAT
Compilato da: Babywhale, Foresight News
L2BEAT ha investito notevoli sforzi sin dal suo inizio per analizzare e comprendere i rischi associati ai protocolli Layer 2. Agiamo sempre nel migliore interesse dei nostri utenti e del nostro ecosistema e facciamo del nostro meglio per essere un supervisore imparziale e indipendente, senza lasciare che le nostre preferenze personali per progetti o team correlati influenzino i fatti. Ecco perché, anche se rispettiamo il tempo e l’impegno che il team di progetto dedica al progetto, potremmo “suonare l’allarme” o sottolineare le nostre preoccupazioni sui potenziali rischi di determinati protocolli. Avere tempestivamente discussioni relative alla sicurezza consente all’intero ecosistema di essere meglio preparato ai potenziali rischi e di reagire prima a qualsiasi comportamento sospetto.
Oggi vorremmo discutere del modello di sicurezza condivisa per le applicazioni cross-chain. Attualmente esistono due modelli di sicurezza: sicurezza condivisa e sicurezza delle applicazioni indipendenti. La sicurezza condivisa è come tutti i rollup. La sicurezza delle applicazioni autonome viene utilizzata principalmente dai progetti "omnichain", che utilizzano principalmente LayerZero.
Sicurezza condivisa contro sicurezza indipendente
La sicurezza condivisa si riferisce a un token o un'applicazione specifica in esecuzione su una determinata infrastruttura e, invece di scegliere liberamente un modello di sicurezza, devono aderire a tutti i requisiti di sicurezza imposti dall'infrastruttura. Ad esempio, gli Optimistic Rollup impongono in genere una finestra finale di 7 giorni: un'applicazione in esecuzione su tali Rollup non può semplicemente ignorare o abbreviare questo periodo. Anche se questo può sembrare un ostacolo, c’è una ragione per questo. Questo periodo fornisce agli utenti la garanzia di sicurezza che, indipendentemente dalla politica di sicurezza interna dell'applicazione, che deve essere rispettata, l'applicazione può solo rafforzare la sicurezza dei Rollup, non indebolirla.
Sicurezza indipendente significa che ogni applicazione è responsabile della definizione della propria sicurezza e non è limitata in alcun modo dall'infrastruttura. All’inizio può sembrare una buona idea, dopo tutto, lo sviluppatore dell’app sa meglio di quali misure di sicurezza l’app potrebbe aver bisogno. Allo stesso tempo, però, trasferisce all’utente finale la responsabilità di valutare i rischi associati a ciascuna policy di sicurezza applicativa. Inoltre, se gli sviluppatori di app sono liberi di scegliere le proprie policy di sicurezza, possono anche modificarle in qualsiasi momento. Pertanto, non è sufficiente valutare il rischio una volta per ciascuna applicazione; occorre valutarlo ogni volta che le politiche di un'applicazione cambiano.
I problemi
Riteniamo che un modello di sicurezza indipendente in cui ciascuna applicazione sia libera di definire la propria politica di sicurezza crei seri problemi di sicurezza. Innanzitutto, aumenta il rischio per gli utenti finali perché devono verificare il rischio per ciascuna applicazione che intendono utilizzare.
La sicurezza autonoma aumenta anche i rischi per le app che utilizzano questo modello, ad esempio aggiungendo ulteriori rischi relativi alle modifiche alle policy di sicurezza: se un utente malintenzionato dovesse modificare il modello di sicurezza dell'app, potrebbe anche semplicemente disabilitarlo, rimanendo così senza denaro o rischiando di farlo. in ogni caso. Non sono presenti ulteriori livelli di sicurezza sull'applicazione per prevenire attacchi.
Inoltre, poiché le policy di sicurezza possono cambiare in qualsiasi momento e in tempo reale, è quasi impossibile monitorare le applicazioni in tempo reale e informare gli utenti dei rischi.
Lo abbiamo trovato simile all’aggiornabilità dei contratti intelligenti, di cui abbiamo messo in guardia su L2BEAT. Informiamo gli utenti sui rollup e sui bridge cross-chain che dispongono di meccanismi di aggiornabilità nei loro contratti intelligenti e sui meccanismi esatti per gestire l'aggiornabilità in ciascun caso. Questo è già piuttosto complesso e l’utilizzo di modelli di sicurezza separati ne moltiplica il numero, rendendo quasi impossibile un monitoraggio efficace.
Questo è il motivo per cui consideriamo un modello di sicurezza autonomo un rischio per la sicurezza in sé e per sé e presupponiamo che ogni applicazione che utilizzerà questo modello per impostazione predefinita dovrebbe essere considerata rischiosa fino a prova contraria.
Dimostrare che esistono vulnerabilità della sicurezza
Abbiamo deciso di testare la nostra ipotesi su mainnet. Il framework LayerZero è stato scelto per la sperimentazione perché è una delle soluzioni autonome incentrate sulla sicurezza più popolari. Abbiamo distribuito un token omnichain sicuro e successivamente abbiamo aggiornato la configurazione di sicurezza per consentire prelievi dannosi del token. Il codice per il token si basa sugli esempi forniti da LayerZero ed è molto simile o identico a molti altri token e applicazioni omnichain distribuiti nella vita reale.
Ma prima di entrare nei dettagli, diamo una breve occhiata a come si presenta il modello di sicurezza LayerZero.
Come sottolinea LayerZero nel suo white paper, la sua “comunicazione inter-catena trustless” si basa su due attori indipendenti (oracoli e relè) che agiscono insieme per garantire la sicurezza del protocollo.
LayerZero afferma sul suo sito web che il suo concetto principale sono "applicazioni utente che eseguono ULN (UltraLightNode), terminali on-chain configurabili". Il componente on-chain di LayerZero si basa su due componenti off-chain esterni per inoltrare messaggi tra catene: oracoli e relè.
Ogni volta che un messaggio M viene inviato dalla catena A alla catena B, si verificano le due operazioni seguenti:
Innanzitutto, l'oracolo attende fino al completamento della transazione che invia il messaggio M sulla catena A, quindi scrive le informazioni rilevanti sulla catena B, come il valore hash dell'intestazione del blocco della catena A contenente il messaggio M (il valore esatto tra diverse catene/oracoli Il formato può variare).
Il relè invia quindi una "prova" (come Merkle Proof) alla catena B, dimostrando che l'intestazione del blocco memorizzato contiene il messaggio M.
LayerZero presuppone che i relè e gli oracoli siano partecipanti indipendenti e onesti. Tuttavia, LayerZero ha anche affermato nel white paper che se questo presupposto non viene soddisfatto, ad esempio, il relè e l'oracolo colludono, con il risultato che "sia l'intestazione del blocco fornita dall'oracolo che la prova della transazione fornita dal relè non sono valide, ma ancora corrispondente."
LayerZero afferma che "il design di LayerZero elimina la possibilità di collusione". Ma in realtà questa affermazione non è corretta (lo dimostreremo negli esperimenti mostrati di seguito), perché ogni applicazione utente può definire i propri relè e oracoli. LayerZero non garantisce fin dalla progettazione che questi componenti siano indipendenti e non possano colludere, piuttosto spetta all'applicazione utente fornire tali garanzie; LayerZero non dispone di alcun meccanismo per arrestare le app se scelgono di interromperle.
Inoltre, per impostazione predefinita, tutte le applicazioni utente possono modificare relè e oracoli in qualsiasi momento, ridefinendo completamente i presupposti di sicurezza. Pertanto, verificare la sicurezza di una determinata applicazione solo una volta non è sufficiente, poiché potrebbe cambiare in qualsiasi momento dopo il controllo, come dimostreremo nei nostri esperimenti.
design sperimentale
Per i nostri esperimenti, abbiamo deciso di creare un semplice token omnichain, CarpetMoon, che funziona sia su Ethereum che su Optimism e utilizza LayerZero per comunicare tra le due catene.
Il nostro token utilizza inizialmente il modello di sicurezza predefinito fornito da LayerZero, rendendolo identico a una grande applicazione LayerZero attualmente distribuita (forse non a tutte). Pertanto, è generalmente sicura come qualsiasi altra moneta che utilizza LayerZero.
Innanzitutto, distribuiamo il nostro contratto token su Ethereum e Optimism:
https://ethtx.info/mainnet/0xf4d1cdabb6927c363bb30e7e65febad8b9c0f6f76f1984cd74c7f364e3ab7ca9/
https://optimistic.etherscan.io/tx/0xf41389d71fa3942de5225efb067072728c6c6de56c241574187781db7c73d221
Impostiamo quindi il routing in modo che LayerZero sappia quale contratto corrisponde a quale su entrambe le catene.
https://ethtx.info/mainnet/0x19d78abb03179969d6404a7bd503148b4ac14d711f503752495339c96a7776e9/
https://optimistic.etherscan.io/tx/0x037b1bad33faa5607bb5835460a1d5caaf3a147dc3a09762ac7703befcdb3c3c
Il token è stato distribuito e assomiglia esattamente a ogni altro token omnichain che utilizza LayerZero, utilizzando la configurazione predefinita e niente di sospetto.
Abbiamo fornito 1 miliardo di token CarpetMoon su Ethereum alla nostra "utente di prova" Alice.
https://ethtx.info/mainnet/0x7e2faa8426dacae92830efbf356ca2da760833eca28e652ff9261fc03042b313/
Ora Alice usa LayerZero per concatenare questi token a Optimism.
Blocchiamo i token in un contratto di deposito a garanzia su Ethereum:
https://ethtx.info/mainnet/0xe4dc3757b86bfda8e7baddc088fb1a599e083ed77034c29e5dd8bd11f1e17771/.
Il messaggio contenente la transazione viene passato a Optimism tramite LayerZero:
https://layerzeroscan.com/101/address/0xc6005ccc1de4b300d538903b74848bff881d5dc5/message/111/address/0x201fe0d843b546f2e24d4c8444318d1c71b7nonced10d/.
I token cross-chain vengono coniati su Optimism e Alice ora possiede 1 miliardo di token MoonCarpet su Optimism:
https://optimistic.etherscan.io/tx/0x5388ced88cf562acafff82d6798f791b0b38b90ee106df9bf91c0d86306ec302.
Tutto funziona come previsto, Alice incrocia i token e vede che ci sono 1 miliardo di token MoonCarpet nel contratto di deposito a garanzia su Ethereum e 1 miliardo di token MoonCarpet nel suo conto su Optimism. Ma solo per assicurarsi che tutto andasse bene, ha trasferito metà dei suoi token su Ethereum.
Iniziamo con una transazione su Optimism che ha bruciato 500 milioni di token:
https://optimistic.etherscan.io/tx/0x118a57106488ad0bae1f3b920b1fd98b187752ad966f3a901fc53cff47f2097f.
Le informazioni sulla transazione vengono passate a Ethereum:
https://layerzeroscan.com/111/address/0x201fe0d843b546f2e24d4c8444318d1c71b7d10d/message/101/address/0xc6005ccc1de4b300d538903b74848bff881d5dc5/nonce/1.
Come previsto, 500 milioni di token MoonCarpet vengono restituiti dal contratto di deposito a garanzia all'indirizzo di Alice:
https://etherscan.io/tx/0x27702e07a65a9c6a7d1917222799ddb13bb3d05159d33bbeff2ca1ed414f6a18.
Finora tutto funziona bene ed esattamente come previsto. Alice ha verificato di poter effettuare il cross-chain dei token da Ethereum a Optimism e viceversa, non ha motivo di preoccuparsi dei suoi token MoonCarpet.
Ma le ipotesi ipotetiche hanno i loro problemi: ad esempio, il team dietro il nostro token ha un problema e il cattivo Bob ottiene l'accesso alla configurazione LayerZero della nostra app.
In questo modo, Bob può modificare gli oracoli e i relè dai componenti predefiniti ai componenti che controlla.
Va notato che questo è un meccanismo fornito per ogni applicazione che utilizza LayerZero ed è radicato nell'architettura di LayerZero. Non è una backdoor di alcun tipo, ma un meccanismo standard.
Quindi Bob cambia l'oracolo in un EOA sotto il suo controllo:
https://ethtx.info/mainnet/0x4dc84726da6ca7d750eef3d33710b5f63bf73cbe03746f88dd8375c3f4672f2f/.
Cambia anche il ripetitore:
https://ethtx.info/mainnet/0xc1d7ba5032af2817e95ee943018393622bf54eb87e6ff414136f5f7c48c6d19a/.
Adesso succede qualcosa di strano. Poiché l'oracolo e il relè sono ora sotto il pieno controllo di Bob, è in grado di rubare i gettoni di Alice. Anche se non è stata intrapresa alcuna azione su Optimism (i token MoonCarpet erano ancora nel portafoglio di Alice), Bob è riuscito a convincere lo smart contract MoonCarpet su Ethereum (utilizzando il meccanismo LayerZero) di aver distrutto i token sull'altra catena ed è stato in grado di ritirare i token sul token MoonCarpet su Ethereum.
Innanzitutto, aggiorna l'hash del blocco di Ethereum utilizzando un oracolo che controlla:
https://ethtx.info/0xde2edee2cc7f070120e96c9df90d86696970befcfc221e18c6ac4168bb5b1d92/.
Ora può ritirare i token rimanenti dal contratto di deposito a garanzia:
https://ethtx.info/0xda695f374b375d5372efeca37aae4c5a17f114d5a76db1e86edebb0924bcdcc7/.
Risultati sperimentali
Alice non sa nemmeno perché e quando si è verificato l'errore. All'improvviso, il suo token MoonCarpet su Optimism non era più supportato da token su Ethereum.
Il contratto intelligente non è aggiornabile e funziona come previsto. L'unica attività sospetta sono le modifiche all'oracolo e al relè, ma questo è un meccanismo regolare integrato in LayerZero, quindi Alice non sa nemmeno se questa modifica è intenzionale. Anche se Alice venisse a conoscenza del cambiamento, sarebbe troppo tardi: l'aggressore potrebbe prosciugare i fondi prima che lei possa reagire.
Non c'è niente che LayerZero possa fare: queste sono tutte implementazioni efficienti dei loro meccanismi, su cui non hanno alcun controllo. In teoria, le applicazioni stesse potrebbero impedirsi di modificare oracoli e relè, ma per quanto ne sappiamo, nessuna applicazione distribuita lo ha fatto.
Abbiamo fatto questo esperimento per verificare se qualcuno se ne fosse accorto ma, come ci aspettavamo, nessuno se ne è accorto. È quasi impossibile monitorare in modo efficace tutte le applicazioni create con LayerZero per verificare se le loro politiche di sicurezza sono cambiate e avvisare gli utenti quando ciò accade.
Anche se qualcuno riuscisse a scoprire in tempo che gli oracoli e i relè sono cambiati e hanno creato un rischio per la sicurezza, sarebbe troppo tardi. Dato che i nuovi oracoli e relè sono ora liberi di scegliere quali messaggi consegnare o semplicemente disabilitare la comunicazione inter-catena, generalmente non c’è molto che gli utenti possano fare al riguardo. I nostri esperimenti mostrano chiaramente che anche se Alice nota il cambiamento nella configurazione dell'applicazione, non può fare molto con i suoi token a catena incrociata: i nuovi oracoli e relè non sono più accettati nel messaggio della catena di comunicazione originale, quindi il messaggio non verrà restituito a Ethereum .
Insomma
Come possiamo vedere, anche se il nostro token è stato creato con LayerZero e ha utilizzato i suoi meccanismi come previsto, siamo stati in grado di rubare fondi dal deposito a garanzia del token. Naturalmente la colpa è dell'applicazione (nel nostro caso del token CarpetMoon) e non di LayerZero stesso, ma dimostra che LayerZero stesso non fornisce alcuna garanzia di sicurezza.
Quando LayerZero descrive il proprio modello di sicurezza relativo a oracoli e relè, presuppone che il proprietario dell'applicazione (o chiunque abbia la chiave privata) non farà nulla di irragionevole. Ma in un ambiente contraddittorio, questo presupposto non è corretto. Inoltre, richiede agli utenti di fidarsi dello sviluppatore dell'app come terza parte fidata.
Quindi, in pratica, non si può fare alcuna ipotesi sulla sicurezza delle applicazioni realizzate con LayerZero: ogni applicazione dovrebbe essere considerata rischiosa fino a prova contraria.
In realtà, tutta la storia è iniziata quando abbiamo pianificato di includere un PR per tutti i token omnichain sul sito Web L2BEAT: avevamo difficoltà a capire come valutare il loro rischio. Analizzando i rischi, ci è venuta l’idea della sperimentazione.
Se L2BEAT diventasse operativo, la conseguenza sarebbe che dovremmo inserire avvisi su ogni applicazione creata con LayerZero per avvisare di possibili rischi per la sicurezza. Ma volevamo avere una discussione più ampia sui modelli di sicurezza perché crediamo che la sicurezza autonoma sia un modello che dovrebbe essere evitato, soprattutto nel nostro campo.
Riteniamo che man mano che modelli di sicurezza indipendenti come LayerZero diventano più popolari, sempre più progetti ne abuseranno, causando danni ingenti e aumentando l’incertezza in tutto il settore.