
Dieser Artikel entstand aus einer Zusammenarbeit zwischen Consensys Diligence und dem MSQ-Projekt mit Unterstützung der DFinity Foundation und MetaMask Snaps DAO

Consensys Diligence ist eine Prüfungsabteilung innerhalb von Consensys Software Inc., die für ihre unübertroffene Expertise bei der Durchführung sorgfältiger Audits in den Bereichen Solidity, Cairo und einer Vielzahl von ZK-Bibliotheken bekannt ist. Das Diligence-Team treibt die Audit- und Sicherheitsstandards für MetaMask Snaps voran und arbeitet eng mit dem MetaMask-Team zusammen, um die Sicherheit der Wallet-Funktion zu gewährleisten. Darüber hinaus ist das Diligence-Team Vorreiter bei der Entwicklung von Sicherheits-Tools und modernsten Continuous-Fuzzing-Lösungen, die in anspruchsvollsten Produktionsumgebungen validiert wurden.
Das MSQ-Projekt wurde kürzlich im MetaMask Snaps Store veröffentlicht. MSQ ist ein Snap, das Nutzern ermöglicht, mit dem Internet Computer-Netzwerk zu interagieren, IC-basierte Token zu verwalten, sich sicher bei IC-basierten Dapps zu authentifizieren und für digitale Güter und Dienstleistungen zu bezahlen. Im Wesentlichen handelt es sich um eine Krypto-Wallet, die in MetaMask integriert ist und speziell für den Internet Computer mit besonderen Funktionen für Authentifizierung und Zahlungen entwickelt wurde.
Gemeinsam haben die Diligence- und MSQ-Teams fünf Schlüsselbereiche für diesen Artikel identifiziert – Dokumentation, Software-Design, Code, Supply Chain und Fehlerbehebungen – und stellen eine Liste der vom MSQ-Team während der Entwicklung eingesetzten Praktiken bereit, ergänzt durch Kommentare des Diligence-Teams, die die Sicherheitsvorteile dieser Praktiken erläutern. Dies macht den Artikel zu einer hilfreichen Ressource für alle, die einen Snap für die MetaMask Wallet oder ein anderes sicherheitskritisches System entwickeln, das einem möglichen Sicherheitsaudit unterzogen werden soll. Fangen wir an!
Dokumentation verwandelt die Konzepte in deinem Kopf in etwas für andere Sichtbares. Mehrschichtige Dokumentation hilft dem Leser, diese Konzepte so zu verstehen, wie du es beabsichtigst, indem er schrittweise in den Kontext eingeführt wird. Je klarer die Dokumentation, desto umfassender der Überblick über dein Projekt und desto besser werden andere dich verstehen.
Wir definieren Dokumentationsebenen in umgekehrter Reihenfolge, wie ein Leser typischerweise auf sie zugreifen würde, wobei jede Ebene einen höheren Abstraktionsgrad bietet. So werden Leser, die mit dem Gesamtbild beginnen, schrittweise in die Details eintauchen.
Die ultimative Informationsquelle über deine Software ist der Code selbst, der als Grundlage deiner Dokumentation dient. Obwohl er alle notwendigen Informationen enthält, ist es schwierig, diese zu verarbeiten. Je sauberer der Code, desto leichter lassen sich die übergeordneten Abstraktionen daraus ableiten. In realen Systemen sind diese Abstraktionen jedoch hinter komplexen Komponenteninteraktionen, wochenlangen technischen Schulden und schnellen, unsauberen Lösungen verborgen.
Zunächst möchtest du also verhindern, dass Personen, die deinen Code lesen, durch komplizierte Teile deines Systems in die Irre geführt werden. Der beste Weg dazu ist, die kognitive Belastung beim Lesen deines Codes zu reduzieren. Einige Strategien umfassen:
Den Code navigierbar gestalten, um eine einfache Durchquerung in IDEs zu ermöglichen.
Ausführliche Benennung verwenden, um Zweck und Funktionalität von Code-Elementen zu verdeutlichen.
Stark typisierte Sprachen einsetzen, um klare Datenformate zu definieren.
Der MSQ Snap und die Dapp-Frontends sind in TypeScript entwickelt, was zahlreiche potenzielle Fehler verhindert hat – im Gegensatz zu den Fallstricken von reinem JavaScript. Ebenso nutzt unser Backend Rust, das für sein robustes Typsystem bekannt ist. Außerdem exportiert der MSQ Snap eine Reihe von Methoden, die von einer Drittanbieter-App ausgeführt werden können. Wir verwenden jedoch keine Strings zur Identifizierung dieser Methoden, sondern Konstanten. Wir haben ein konstantes Objekt wie dieses:
Im Code kann dieses konstante Objekt als Leitfaden für den Zugriff auf die richtige Methode verwendet werden, und Leser können anhand des Bezeichners im Objekt viel über diese Methode erfahren. Zum Beispiel kann die Methode SNAP_METHODS.protected.identity.login nur von MSQs Companion-Dapp ausgeführt werden und ermöglicht dem Nutzer die Anmeldung. Dieser Ansatz verbessert die Code-Klarheit und vereinfacht das Refactoring, da Änderungen an Methodennamen zentral verwaltet werden, anstatt an mehreren Stellen aktualisiert zu werden.
Zum Abgleich von Methodennamen verwenden wir einen großen Switch-Ausdruck mit Branches wie diesem:
Wie du sehen kannst, ist es beim Lesen sehr schwer, etwas falsch zu interpretieren – alles ist präzise benannt und lässt keinen Raum für Interpretationen.
Kommentar von Diligence Zeit ist ein entscheidender Faktor. Während Entwickler Wochen haben, um eine Codebasis zu verstehen, haben Sicherheitsingenieure oft nur Tage, um Risiken zu identifizieren. Diese Einschränkung unterstreicht die Bedeutung der Reduzierung kognitiver Belastung im Code – eine Praxis, die sowohl der Entwicklereffizienz als auch der Sicherheit zugute kommt.
Was wir aus MSQs Codebasis lernen können: Klarer, navigierbarer Code mit beschreibenden Bezeichnungen und starker Typisierung (wie TypeScript) reduziert Missverständnisse, eine häufige Quelle von Schwachstellen.
Denke jedoch daran, dass TypeScript-Typannotationen nur zur Compile-Zeit überprüft werden! Für alle Daten, die zur Laufzeit verarbeitet oder geparst werden (RPC, JSON, ...), sind zusätzliche Typerzwingungen, Datenformat- und Bereichsprüfungen erforderlich! Zu diesem Zweck setzt MSQ elegant zod ein, eine TypeScript-first Schema-Validierungsbibliothek mit statischer Typinferenz, und wir würden Teams empfehlen, diesem Ansatz zu folgen.
MSQ hat den richtigen Mittelweg gefunden, indem es Code-Absichten durch das richtige Maß an Kommentaren klar macht. Diese Klarheit hilft Sicherheitsforschern, den „roten Faden" und die Kernkonzepte der Codebasis schnell zu erfassen. Durch das Schreiben von leicht verständlichem Code steigern Entwickler die Effektivität schneller Sicherheitsüberprüfungen erheblich.
Wir glauben, dass Kommentieren nicht bedeutet, 100 % deines Codes abzudecken. Es ist entscheidend, Teile zu annotieren, die komplex oder schlecht geschrieben sind. Bereiche wie reguläre Ausdrücke, Kryptographie und String-Manipulationen profitieren besonders von klaren Kommentaren.
Zum Beispiel haben wir bei MSQ eine Funktion, die mögliche Markdown-Steuerzeichen in einem String escaped. Ihr Körper ist eine einzelne Codezeile, aber es gibt einen regulären Ausdrucks-Abgleich, daher beschreiben wir ihre Funktionalität in einem Kommentar:
Wenn du KI in deinem Workflow nicht ablehnst, ist ChatGPT hervorragend darin, schnell gute Kommentare für solche Hilfsfunktionen zu generieren (überprüfe die Ausgabe jedoch immer sorgfältig).
Kommentar von Diligence Als Sicherheitsprüfer nutzen wir Funktionskommentare als Wegweiser durch unbekannten Code. Denke daran, dass wir nur begrenzte Zeit für die Code-Überprüfung haben, und wenn Kommentare nicht mit der Implementierung übereinstimmen, ist das nicht nur verwirrend – es ist ein Warnsignal.
Sie zeigen oft, dass entweder die Funktion oder ihre Beschreibung von der Spezifikation abweicht, was auf potenzielle Schwachstellen hinweist. Vielleicht überspringt eine Funktion versprochene Prüfungen oder verarbeitet Daten unerwartet, was zu schwerwiegenden Konsequenzen führen kann.
Halte deine Kommentare daher präzise und genau, ähnlich wie MSQ es in seiner Codebasis tut. Inline-Kommentare sind nicht nur Notizen; sie sind Leuchttürme, die uns durch deinen Code führen, und Unstimmigkeiten sind Hinweise, dass etwas nicht stimmen könnte.
Nachdem du sichergestellt hast, dass dein Code und seine Komplexitäten gut dokumentiert sind, ist der nächste Schritt, die Systemarchitektur zu skizzieren. Dies beinhaltet die Detaillierung der Interaktionen zwischen Komponenten sowie der Protokolle, Algorithmen und Datenstrukturen, die deine Software verwendet. Diese Ebene verwendet hauptsächlich menschenlesbare Formate wie Text und Diagramme anstelle von Code.
MSQs Systemdokumentation umfasst eine Architekturübersicht und einen Integrationsleitfaden. Diese Dokumente, reich an Textbeschreibungen, Beispielen und Diagrammen, verdeutlichen, wie verschiedene Systemteile interagieren.
Sequenzdiagramme sind unschätzbar wertvoll für die Visualisierung von Komponenteninteraktionen. Wir empfehlen diagrams.net (draw.io), ein kostenloses Tool, das sich in verschiedenen Projekten als vielseitig erwiesen hat.
Kommentar von Diligence Im Gegensatz zu Inline-Kommentaren, die Funktionen detaillieren, bieten Systemdokumente eine Vogelperspektive und zeigen die gesamte Landschaft einer Anwendung. Diese Perspektive ist entscheidend, um komponentenübergreifende Probleme oder Schwachstellen im Nutzerfluss zu erkennen, die auf Code-Ebene oft unsichtbar sind.
Stell dir eine Sicherheitsüberprüfung wie ein Spiel von Command & Conquer vor. Du beginnst mit einer größtenteils verdeckten Karte. Während du erkundest, fungieren Systemdokumente wie Aufklärungseinheiten, die die vollständige Architektur enthüllen – Berechtigungen, Snap-Dapp-Interaktionen, Nutzerinteraktionen. Diese sich entfaltende Übersicht ermöglicht es Prüfern, Nutzerreisen zu verfolgen, ähnlich wie das Verfolgen von Spieleinheitenbewegungen, um Pfade zu erkennen, die die Sicherheit umgehen könnten.
Darüber hinaus sollten umfassende Systemdokumente sicherheitsrelevante Anmerkungen und idealerweise Ergebnisse einer Bedrohungsmodellierungsübung enthalten. Sie sollten einen klaren Überblick über die Hauptkomponenten, Interaktionen, Risiken, Akteure und typische Nutzerflüsse bieten. Dies hilft Prüfern, sich auf Hochprioritätsbereiche zu konzentrieren und Abweichungen von der Spezifikation zu erkennen.
Für Entwickler ist gute Systemdokumentation nicht nur Papierkram; sie ist eine gemeinsame Karte, die offensive und defensive Strategien leitet und Sicherheitsüberprüfungen von blinden Sondierungen in strategische Operationen verwandelt.
Diese Ebene umfasst eine Vielzahl von Materialien wie Artikel, Landing Pages, Blog-Beiträge, Demo-Videos und mehr.
Diese Informationen betreffen hauptsächlich geschäftliche Aspekte, aber sie beantworten in hohem Maße die Frage „Was?", während alle vorherigen Ebenen die Frage „Wie?" mit unterschiedlichem Detailgrad beantwortet haben.
Ein Neuling wird dein Projekt höchstwahrscheinlich durch solches Material kennenlernen, daher ist es eine gute Idee, diese Ebene so einfach und visuell wie möglich zu halten. Außerdem ist diese Art von Material in der Regel das einzige, das die Software in Aktion zeigt – wie ein Nutzer mit deiner Software von Zustand A zu Zustand B gelangen kann. Indem sie sie in Aktion sehen, machen sich die Menschen mit der Hauptidee deiner Software vertraut und können Vermutungen darüber anstellen, wie diese Software unter der Haube funktioniert.
Zum Beispiel sagt MSQs Landing-Page-Hero-Screen in großen Buchstaben: „USE THE INTERNET COMPUTER WITH METAMASK". Nach dem Lesen dieses einfachen Satzes würde der Leser wahrscheinlich vermuten: „Ah, das ist also ein Wallet-Snap, der Token von der Internet Computer-Blockchain speichern kann. Es funktioniert wahrscheinlich genauso wie andere Snaps für andere Blockchains, nur mit Technologien aus dem IC-Entwickler-Ökosystem" – was eine 100 % korrekte Vermutung ist.
Kommentar von Diligence Unsere Erfahrung mit MSQ und zahlreichen anderen Blockchain-Projekten hat durchgängig gezeigt, dass klare, übergeordnete Dokumentation nicht nur vorteilhaft ist – sie ist entscheidend für die Nutzerakzeptanz und die Sicherheit. Bei unserer Überprüfung von MSQs Snap waren wir positiv überrascht von ihrem mehrschichtigen Dokumentationsansatz. Ein Video-Walkthrough ihres Entwicklers brachte uns schnell auf den neuesten Stand. Wir konnten die Funktionen des Snaps verstehen, noch bevor wir uns den Code ansahen. Dieser übergeordnete Überblick zeigte die Benutzeroberfläche, komplett mit Kommentaren zu erwarteten Verhaltensweisen und typischen Nutzerflüssen. Solche visuellen Hilfsmittel sind unschätzbar wertvoll und ermöglichen es Sicherheitsexperten, die beabsichtigten „Happy Paths" der Anwendung viel schneller zu erfassen und nach Schwachstellen zu suchen, die oft abseits dieser Pfade verborgen sind. Dies, kombiniert mit einem Live-Walkthrough des Snaps und des Codes, ist typischerweise der ideale Start für eine Sicherheitsüberprüfung.
Dieser Teil ist wahrscheinlich der wichtigste für die Sicherheit deines Projekts. Dein Code kann zu 100 % fehlerfrei sein, und deine Infrastruktur kann mit Maßnahmen im Wert von Millionen von Dollar geschützt sein. Aber all diese Bemühungen wären bedeutungslos, wenn dein Design einen grundlegenden Fehler enthält, der von böswilligen Akteuren ausgenutzt werden kann.
Während spezifische Beispiele je nach Anwendungsfall variieren, bieten wir mehrere universelle Tipps.
Zu Beginn von MSQ haben wir grundlegende Sicherheitsprinzipien etabliert, die mit unserer Vision übereinstimmen:
Das MSQ-Team weiß nichts: Wir sammeln keine nutzersensiblen Informationen, einschließlich Schlüsselmaterial, Autorisierungssitzungsdaten oder Kontodetails.
Kryptographisches Material verlässt den Snap nie: Geschützte MetaMask-Entropie des Nutzers wird ausschließlich innerhalb des Snaps verarbeitet, bei Bedarf generiert und unmittelbar nach der Verwendung verworfen.
MSQ ist deterministisch: Nutzer können alle Gelder, Identitäten und Schlüsselpaare deterministisch mit ihrer Root-Seed-Phrase wiederherstellen, ohne zusätzliches Wissen zu benötigen.
MSQ priorisiert Privatsphäre: Unsere Bemühungen priorisieren die Privatsphäre der Nutzer über alles andere.
Diese Prinzipien sind auf MSQs spezifische Bedürfnisse zugeschnitten. Das MetaMask-Team stellt jedoch auch eine Reihe von Sicherheitsrichtlinien für Snap-Entwickler bereit, die MSQ einhält und die hier verfügbar sind.
Zum Beispiel gibt es das Prinzip der Minimalen Berechtigungen, das im Wesentlichen bedeutet, dass je weniger Berechtigungen dein Snap von einem Nutzer anfordert, desto besser seine Sicherheit ist. MSQ fordert nur 4 Berechtigungen an:
endowment:rpc
snap_dialog
snap_manageState
snap_getEntropy
Wir benötigen kein endowment: network access, da MSQ nur für das Signieren von Transaktionen verantwortlich ist, nicht für deren Übermittlung an den IC – dafür ist die integrierende Dapp verantwortlich.
Du solltest dasselbe in deinem Snap tun – nimm die Standard-Richtlinie von MetaMask, erweitere sie mit deinen spezifischen Regeln und befolge sie.
Kommentar von Diligence Wir sagen unseren Kunden: „Sicherheit ist kein Feature, das man hinzufügt; es ist ein Prinzip, um das man herum designt." MSQs Etablierung grundlegender Sicherheitsprinzipien zu Projektbeginn ist genau das, wonach wir suchen. Zu oft behandeln Projekte Sicherheit als nachträglichen Gedanken und fügen Maßnahmen hinzu, nachdem die Kernarchitektur festgelegt ist. Dieser Nachrüstungsansatz hinterlässt unweigerlich grundlegende Mängel, die Code-Level-Fixes nicht wirklich beheben können.
Bei Consensys Diligence bieten wir Sicherheitsexpertendienste und Tools an und setzen uns für die Rechte der Endnutzer ein. Dazu gehört die Sicherstellung, dass das Schlüsselmaterial der Nutzer innerhalb der Wallet-Vertrauensgrenzen sicher bleibt und nie unbeabsichtigt außerhalb dieser Zone exponiert wird. Wir konzentrieren uns auch auf den Schutz der Nutzerprivatsphäre und versuchen idealerweise, sogar Metadaten- oder Seitenkanal-Informationslecks an Dritte zu verhindern. Darüber hinaus setzen wir uns dafür ein, dass Snaps nur die für die Funktionalität notwendigen Mindestberechtigungen anfordern – das Prinzip der geringsten Privilegien.
MSQs proaktive Haltung stimmt mit diesen Prinzipien überein. Indem sie Sicherheit von Anfang an priorisieren, bauen sie ein stärkeres Fundament – eines, das von Natur aus widerstandsfähiger gegen Schwachstellen ist.
Dies ist eher eine Meta-Richtlinie – es ist ein Prinzip, das in jeder Software implementiert werden sollte: von Online-Spielen bis hin zu Bankensystemen.
Das bemerkenswerteste Beispiel dafür bei MSQ ist unser Ansatz zum Identitätsmanagement. Wie du vielleicht weißt, stellt die Mehrheit der Wallets dem Nutzer eine Reihe von Identitäten (Adressen, Konten usw.) zur Verfügung. Auf diesen Satz kann jede Dapp mit Zustimmung des Nutzers zugreifen. Zum Beispiel, um einige Transaktionen zu signieren.
Dies ist sehr nützlich für Integrationen zwischen Dapps, da jede Dapp Smart-Contract-Methoden anderer Dapps im Namen des Nutzers aufrufen und so gegenseitig ihre Fähigkeiten erweitern kann. Zum Beispiel kann eine Krypto-Zahlungsplattform Uniswaps Smart Contracts aufrufen, um die Token des Käufers automatisch zu tauschen, damit sie dem entsprechen, was der Verkäufer als Zahlung für ein bestimmtes Gut oder eine Dienstleistung erwartet.
Dies ist jedoch sicherheitsschädlich, da Betrugswebsites Menschen dazu verleiten können, bösartige Transaktionen zu signieren und ihre Wallets zu leeren.
Im Gegensatz dazu übernimmt MSQ die Identity-Scoping-Technik – jede Dapp (jeder eindeutige URL-Ursprung) hat ihren eigenen separaten Satz von Nutzeridentitäten, mit denen sie interagieren kann, ohne die Möglichkeit, mit Nutzeridentitäten anderer Dapps zu interagieren. Dies löst nicht nur das Problem der Betrugswebsites, sondern hilft auch erheblich bei der Privatsphäre, da Dapps den Nutzer nicht mehr verfolgen und sehen können, mit welchen Smart Contracts (die im IC Canisters genannt werden) er interagiert. Diese Methode, inspiriert von Internet Identity und der WebAuthn-Spezifikation, mindert Sicherheitsrisiken erheblich.
Wenn beispielsweise eine bekannte Dapp kompromittiert wird, wären traditionelle Wallets über alle Dapps hinweg anfällig. Im Gegensatz dazu begrenzt MSQs Identity-Scoping die Bedrohung auf die kompromittierte Dapp und verhindert weitreichenden Schaden.
Diese Methode schränkt jedoch die direkte Integration zwischen Dapps ein, da Nutzer auf jeder Dapp unterschiedliche Identitäten haben. MSQ bietet Lösungen für spezifische Szenarien an, wie z. B. das Ermöglichen der Identitätsfreigabe zwischen Dapps mit doppelter Zustimmung, was für Situationen wie Domänennamenänderungen nützlich ist.
Darüber hinaus stellt MSQ sicher, dass die Daten, auf die eine Dapp zugreifen kann, streng an die relevante Identität gebunden sind, was die Nutzerinformationen weiter sichert und die Privatsphäre über verschiedene Anwendungen hinweg wahrt.
Kommentar von Diligence Der Kompromiss der eingeschränkten direkten Dapp-Integration ist eine durchdachte Entscheidung. Bei unseren Risikobewertungen diskutieren wir oft das „Sicherheitsbudget" – in Anerkennung der Tatsache, dass perfekte Sicherheit die Funktionalität beeinträchtigen kann. MSQ hat dieses Budget weise eingesetzt. Durch die Einschränkung von Dapp-übergreifenden Interaktionen haben sie eines der schwerwiegendsten Risiken (weitverbreiteter Identitätsmissbrauch) drastisch reduziert und dabei die Kernfunktionen der Wallet erhalten.
Wir haben bereits ein wenig über den Code gesprochen, als wir die Dokumentation diskutiert haben. Hier möchten wir einige andere Aspekte des Codes betonen, die mehr mit der Technik als mit der Lesbarkeit zusammenhängen.
„Solide" bedeutet hier, dass sich der Code vorhersehbar verhält und alle erwarteten und unerwarteten Eingaben abdeckt. Wie sollte dein Snap beispielsweise reagieren, wenn er einen base64-String erhält, aber hex erwartet? Oder wenn Methoden in einer unbeabsichtigten Reihenfolge aufgerufen werden oder eine undefinierte RPC-Methode aufgerufen wird?
Um diese Unsicherheiten zu adressieren, ist Folgendes erforderlich:
Klare Fehlerbehandlung: Stelle sicher, dass jeder Branch und jeder Fall in deinem Code überprüft und angemessen behandelt wird. Im MSQ Snap verwenden wir TypeScripts exhaustive Checks in Switch-Case-Anweisungen, um unerwartete Methodenaufrufe abzufangen, wie unten gezeigt:
Dieses Setup erfasst Fälle, in denen ein unbekannter RPC-Methodenbezeichner verwendet wird.
Eingabebereinigung: Die Validierung von Eingabedaten gegen erwartete Typen und Formate kann komplex sein, ist aber für die Sicherheit unerlässlich. Wir verwenden die zod-Bibliothek in TypeScript dafür und erweitern TypeScripts Typsystem auf Laufzeitprüfungen. Zod ermöglicht detaillierte Schema-Definitionen und stellt sicher, dass nur gültige Daten verarbeitet werden.
Zum Beispiel verwendet unsere Methode SNAP_METHODS.protected.identity.login ein Zod-Schema zur strengen Validierung der Eingabe:
Hier sind ZOrigin und ZIdentityId keine bloßen Strings oder Zahlen, sondern speziell validierte Untertypen, die sicherstellen, dass Eingaben nicht nur typkorrekt, sondern auch kontextuell angemessen sind.
Durch möglichst präzise Definition von Zod-Schemas kannst du viele potenzielle Probleme präventiv lösen. Auditoren empfahlen die Durchsetzung strenger Validierung in MSQ, was nach der Implementierung mehrere Sicherheitsrisiken identifizierte und behob.
Kommentar von Diligence Es ist nicht das erste Mal, dass wir von unseren Kunden hören, dass die Implementierung strengerer Validierung basierend auf unseren Empfehlungen für ein bestimmtes Angriffsszenario mehrere andere Sicherheitsrisiken aufgedeckt hat. Dies spiegelt unsere Erfahrung genau wider, und deshalb setzen wir uns immer für strenge Eingabevalidierung ein, um die Angriffsfläche zu reduzieren. Bei vielen Sicherheitsüberprüfungen beginnen wir damit, die Eingabevalidierung zu untersuchen. Die Verschärfung dieser Validierung legt oft verborgene Probleme offen – ein Dominoeffekt, bei dem die Behebung einer Schwachstelle eine andere aufdeckt. Es ist ein klares Signal, dass das Projekt unser Feedback ernst nimmt und sein System iterativ härtet. Mit reduzierter Angriffsfläche wird es für Angreifer zunehmend schwieriger, Schwachstellen erfolgreich auszunutzen.
Bei MSQ betrachten wir es als unsere Pflicht, Dapp-Entwicklern eine intuitive Bibliothek bereitzustellen, die eine korrekte und effiziente Interaktion mit unserem Snap ermöglicht. Dies ermöglicht nicht nur MSQ, sondern auch Drittentwicklern, saubere und solide Codebasen zu pflegen.
Eine solche Bibliothek ist aus mehreren Gründen vorteilhaft:
Vereinfacht API-Komplexität: Wir abstrahieren die Komplexitäten des Snaps in eine benutzerfreundliche API. Zum Beispiel verwendet MSQs Client-Bibliothek CBOR für die Datenkodierung, umgeht die Einschränkungen von JSON-RPC und erspart Entwicklern den Aufwand der manuellen Datenkodierung und -dekodierung.
Gewährleistet sichere und direkte Interaktionen: Bestimmte Snap-Funktionalitäten sind exklusiv für unsere Companion-Dapp. Um dies zu ermöglichen, verwalten wir die Umleitungs- und Datenübertragungsprozesse und gewährleisten einen nahtlosen Fluss über postMessage. Diese interne Handhabung garantiert, dass Drittentwickler über eine klare, unkomplizierte API mit unserem Snap interagieren.
Verbessert semantische Klarheit: Eine saubere API ist mehr als nur ein Tool; sie ist ein Kommunikationsmedium, das den Code lesbarer und verständlicher macht, frei von der Unübersichtlichkeit komplizierter Kodierungs-/Dekodierungsprozesse und zusätzlicher Betriebsebenen.
Durch die Priorisierung dieser Aspekte zielt MSQ darauf ab, ein Ökosystem zu schaffen, in dem sowohl unser Snap als auch die integrierenden Dapps effizient und sicher betrieben werden können.
Kommentar von Diligence MSQs Ansatz zur Drittanbieter-Code-Integration durch ihre Bibliothek demonstriert ein Engagement für die Vereinfachung der Entwicklung bei gleichzeitiger Aufrechterhaltung der Sicherheit. Während Sicherheit im Kern streng im Snap-Kontext durchgesetzt werden muss, kann eine Dapp-seitige Bibliothek eine bequeme Möglichkeit zur Kommunikation mit dem Snap bieten. Es sollte jedoch immer beachtet werden, dass der Dapp-Entwickler eine sichere Interaktion mit dem Snap und eine sichere Datenkodierung sicherstellen muss, wenn diese im Kontext der Dapp verwendet wird.
Der jüngste XZ-Backdoor hat erneut betont, wie wichtig es ist, zu verhindern, dass bösartiger Code in deine Abhängigkeiten gelangt. Bei MSQ verwenden wir pnpm zur Verwaltung von Abhängigkeiten, aber es macht eigentlich keinen Unterschied, welchen Paketmanager du bevorzugst. Es gibt zwei Dinge, die wir bei MSQ tun, um uns gegen solche Angriffsvektoren zu schützen:
Die Verwendung von pnpm install --save <package-name> installiert typischerweise die neueste Version eines Pakets gemäß der Semver-Spezifikation, die automatische Updates auf nicht-brechende neuere Versionen erlaubt. Dies wird durch das Caret-Symbol (^) in package.json angezeigt, das einen Bereich akzeptabler Versionen signalisiert:
"zod": "^3.22.4" // Installs version 3.22.4 or newer up to 4.0.0Um Risiken durch bösartige Updates zu verhindern, ist es jedoch sicherer, Abhängigkeiten auf spezifische Versionen zu sperren:
Entferne das Caret (^) aus deiner package.json, um jede Abhängigkeitsversion festzulegen. Entferne vorhandene Lock-Dateien und node_modules, dann führe pnpm install aus, um strikt mit den definierten Versionen übereinzustimmen.
Verwende das --save-exact-Flag für zukünftige Installationen (pnpm install --save-exact <package-name>), um automatische Updates zu vermeiden.
Vertrauen ist ein Faktor bei dieser Entscheidung. Zum Beispiel betrachten wir bei MSQ die Abhängigkeits-Namespaces @metamask und @dfinity als sicher und erlauben Updates innerhalb ihres Semver-Bereichs. Sei dabei jedoch vorsichtig bei potenziellen Schwachstellen durch transitive Abhängigkeiten.
Kommentar von Diligence Die Umstellung von Projekten auf exakte Abhängigkeitsversionen hat unzählige Probleme verhindert:
Es hat stille Updates verhindert, die gepatchte Schwachstellen wieder eingeführt hätten.
Es hat „Version Skew" verhindert, bei dem verschiedene Module unterschiedliche Bibliotheksverhalten sehen.
Es war entscheidend bei Post-Incident-Untersuchungen, da wir die genaue Umgebung replizieren konnten. Jedes nächste Update kann bösartig sein, in jedem Namespace, jedem Paket. Durch die Überprüfung verwendeter Pakete und das Binden nur an bekannte sichere Versionen, um versehentliche Updates zu verhindern, wird die Angriffsfläche für Supply-Chain-Angriffe weiter reduziert. Bestimmten Anbietern zu vertrauen ist in Ordnung, solange neue Versionen manuell auf bösartigen Code überprüft werden, bevor sie verwendet werden. Beachte, dass besonders bekannte Pakete, die von vielen Projekten verwendet werden, bevorzugte Ziele für böswillige Akteure sind, und wie die Vergangenheit gezeigt hat, kann jede solche Kernbibliothek ausgefeilten Supply-Chain-Angriffen zum Opfer fallen (siehe XZ-Backdoor-Angriff)
Um Konsistenz in deinem Team zu gewährleisten und reproduzierbare Builds zu ermöglichen, committe deine Lockfiles in das Versionskontrollsystem. Bei MSQ nutzen wir pnpm workspaces und turborepo, was eine einzelne Root-Lockfile pnpm-lock.yaml erfordert. Dein Setup könnte jedoch die Pflege mehrerer Lockfiles erfordern; alle sollten versionskontrolliert sein, um Umgebungskonsistenz zu garantieren.
Kommentar von Diligence
Diese Praxis, die manchmal als bloße Entwicklungsannehmlichkeit übersehen wird, ist tatsächlich ein kritischer Bestandteil der Aufrechterhaltung einer sicheren und stabilen Codebasis. Unsere jahrelange Prüfung von Smart Contracts, Blockchain-Komponenten und jetzt MetaMask Snaps hat wiederholt gezeigt, dass reproduzierbare Builds nicht nur ein Nice-to-have, sondern eine grundlegende Sicherheitsanforderung sind. Das Committen von Lockfiles ist ein Puzzlestück zur Reduzierung der Angriffsfläche für Supply-Chain-Angriffe. Wenn npm install keine Lotterie mehr ist, hinterlassen konkrete Versionen und Checksums einen Audit-Trail im Repository, Builds sind deterministischer, und „Works on my Machine"-Diskussionen gehören der Vergangenheit an.
Obwohl dies nicht direkt mit unserem Snap zusammenhängt, ist es wichtig zu verstehen, wie man Audit-Befunde effizient behebt.
Sobald das Auditorenteam einen Befund meldet, solltest du mit der Arbeit an einer Lösung beginnen. Die Größe und Komplexität der Lösung hängt eindeutig vom Befund ab, aber es gibt einen Ratschlag, sie kleiner und sauberer zu machen – behebe die Ursache, nicht das Symptom, wo möglich.
Zum Beispiel entdeckten die Auditoren bei MSQ, dass es möglich ist, Markdown-Steuerzeichen in unsere MetaMask-Zustimmungsnachrichten einzuschleusen. Anstatt jede einzelne Zustimmungsnachricht zu korrigieren und mehrere Änderungen in verschiedenen Teilen des Codes vorzunehmen, haben wir einfach die text()- und heading()-Elemente (aus @metamask/snaps-sdk) neu definiert, sodass sie ihren Inhalt zuerst durch die escapeMarkdown()-Funktion leiten und ihn erst dann rendern. Dies ermöglichte es uns, einfach die import-Ausdrücke in allen Dateien mit Zustimmungsnachrichten durch unsere benutzerdefinierten Elemente zu ersetzen, anstatt jeden Aufruf von text() und heading() separat zu korrigieren, was eine viel sauberere Lösung war.
Eine effektive Behebung verbessert nicht nur das spezifische Problem, sondern sichert auch präventiv gegen unsichtbare Schwachstellen.
Kommentar von Diligence Zu oft sehen wir, dass Projekte einen Whack-a-Mole-Ansatz zur Sicherheit verfolgen und jedes einzelne Problem beheben, sobald es auftaucht, ohne die zugrunde liegende Schwachstellenklasse zu berücksichtigen. Indem sie die Grundursache von Problemen angehen und nicht davor zurückschrecken, Schwachstellenklassen global zu beseitigen, zeigt MSQ, dass es Sicherheit nicht als eine Reihe von Patches, sondern als ganzheitliche Disziplin versteht. Als Sicherheitsexperten können wir unseren Kunden nur empfehlen, Korrekturen nicht zu überstürzen und sich genug Zeit zu nehmen, um einen Sicherheitsbefund in ein Ereignis zu verwandeln, das einen positiven Effekt auf die Sicherheit des Projekts hat.
Damit schließen wir unsere Einblicke in die erfolgreiche Durchführung eines MetaMask Snaps-Sicherheitsaudits ab. Die Befolgung dieser Richtlinien hat dem MSQ-Team geholfen, einen positiven Bericht vom Diligence-Team zu erhalten. Wir hoffen, dass die Weitergabe der MSQ-Erfahrung dir bei deinen Sicherheitsaudit-Vorbereitungen helfen wird und einen gründlichen und effektiven Prozess gewährleistet.
Consensys Diligence hat einer Vielzahl von Projekten im gesamten Blockchain-Ökosystem geholfen, sicherzustellen, dass ihre Protokolle startbereit und zum Schutz der Nutzer gebaut sind. Wir überprüfen deinen Snap gerne auf diese und weitere Schwachstellen in einem maßgeschneiderten Audit. Melde dich bei uns und hol dir ein Angebot!
KI-übersetzt. Kann Fehler enthalten. Bitte überprüfen Sie die Informationen stets.