
0. Rückblick
- Das Solana-Ökosystem sichern (1) — Hallo Solana
- Das Solana-Ökosystem sichern (2) — Aufrufe zwischen Programmen
- Das Solana-Ökosystem sichern (3) — Programm-Upgrade
1. Überblick
Im vorherigen Blog haben wir besprochen, wie ein Programm aktualisiert werden kann. In diesem Beitrag stellen wir die Probleme im Zusammenhang mit der Zugriffskontrolle vor, die eines der häufigsten und grundlegendsten Sicherheitsthemen im Bereich DeFi darstellt.
2. Instruktionen
In Solana exportiert jedes Programm einen einzigen entrypoint, der mit entrypoint! definiert wird. Anders als bei Ethereum können Clients nur eine einzige Funktion aufrufen, die als Entrypoint definiert ist und üblicherweise process_instruction genannt wird. Die Entrypoint-Funktion empfängt drei Parameter: die Programm-ID des Smart Contracts, die Konten, auf denen das Programm operieren wird, sowie die Instruktionsdaten. Die Instruktionsdaten legen fest, welche Instruktion aufgerufen wird. Die folgende Abbildung zeigt ein Beispiel. Durch Entpacken der Instruktionsdaten werden verschiedene Instruktionen (z. B. Lock, Unlock) ausgewählt. Daher sind die Instruktionen, die vom Entrypoint aus erreichbar sind, für jedermann öffentlich zugänglich und können mit bestimmten Instruktionsdaten ausgeführt werden.

3. Kontovalidierung
Wie erwähnt, empfängt das Programm die Konten, die es lesen oder schreiben muss. Dieses Design wirft zwei Fragen auf. Für die zu lesenden Konten: Wie lässt sich garantieren, dass die in den Konten gespeicherten Daten vertrauenswürdig sind? Für die zu schreibenden Konten: Wie lässt sich garantieren, dass nur berechtigte Benutzer die Instruktionen zum Schreiben in die Konten aufrufen können? Im Folgenden veranschaulichen wir das Zugriffskontrollproblem. Alle Testcodes sind hier zu finden.
3.1 Code-Überprüfung (PrivilegeOwner)


Wir definieren zunächst zwei Strukturen: Door und Config. Nur das in der Struktur door angegebene Schlüsselkonto (Zeile 17) kann die erstellte door öffnen. Die Tür kann jedoch nicht geöffnet werden, wenn der Systemzustand gesperrt ist, was in der Struktur Config festgelegt ist (Zeile 81).

Wie erwähnt, legt das Config-Konto fest, ob die Tür geöffnet werden kann. In diesem Fall sollte es im Programm nur ein Config-Konto geben. Um dies zu erreichen, verwenden wir PDA, um die Daten von Config zu speichern. Nach der Initialisierung des Config-Kontos setzen wir das Attribut is_initialized auf true, sodass es von Angreifern nicht erneut initialisiert werden kann (Zeile 108 - Zeile 110).

Die Instruktion Open() wird verwendet, um Türen zu öffnen. Die Instruktion empfängt mehrere Konten, darunter das zu öffnende Türkonto, das config-Konto und das owner-Konto, das die door öffnen möchte. Um sicherzustellen, dass die Tür zum Programm gehört und die Konfiguration gültig ist, prüfen wir den Eigentümer des door-Kontos und des config-Kontos (Zeile 204 - Zeile 205). Dies verhindert, dass böswillige Benutzer gefälschte Konten einschleusen. Damit wird unsere erste Frage beantwortet: Um sicherzustellen, dass das zu lesende Konto vertrauenswürdig ist, müssen wir den Eigentümer des Kontos überprüfen! Beachten Sie, dass nur der Eigentümer des door-Kontos die Tür öffnen kann. In diesem Fall prüfen wir, ob das Eigentümerkonto der echte owner der door ist und, was noch wichtiger ist, ob die Instruktion vom Eigentümer autorisiert wurde (Zeile 217 - Zeile 219).

In der Funktion validate_owner() prüfen wir zunächst, ob die öffentlichen Schlüssel der beiden Konten identisch sind, und dann die Signatur des Eigentümers. Dies beantwortet die zweite Frage: Um sicherzustellen, dass nur berechtigte Benutzer die open-Instruktion aufrufen können, müssen wir den Eigentümer und den Unterzeichner des Kontos überprüfen. Die close-Instruktion ist ähnlich wie open und die Details sind im Code zu finden.
Wir haben das Programm im Testnetz bereitgestellt, es ist unter folgendem Link zu finden.
https://explorer.solana.com/address/2Q7FFMWCthBvc6ubLQRx9TRswvaimmd66VaCAfHwsYuC?cluster=testnet
Alle Test-Transaktionen sind unten aufgeführt. Der gesamte Ablauf dieser Transaktion ist AllocatePDA()-> InitializeDoor()-> InitializeConfig()-> Unlock() -> Open() -> Close().
https://explorer.solana.com/tx/2X9CyMrHTNEvbzXTE95gem2j8spnvsQsabFeSpV8hiNpYjiQPPzLRqt5KN86ZYRjnQvydvs7y5eUjJK7no8knDhk?cluster=testnet
https://explorer.solana.com/tx/2XfVWiXeQeHbpqAEYm3AH2RU6hunnqtr155EC4EAM5Bq9VVZNP6QocAav9cPjEQdJFcQrbsSSxiKadr4HPMov8pz?cluster=testnet
https://explorer.solana.com/tx/5Em41sg7yFXeNpnEJnhUQJanfLWKwjMqiBeNAqEEzFrSN9P8zKKafcv5F7RKT2pseB171qeoa8Uz4fKgazzayCnW?cluster=testnet
https://explorer.solana.com/tx/2PMtzpSgjnKDLGmRWBdUSFBPimWnudCPekUYbWzPzokENFYa4N4ab4HCtynfGrzswFPTgGYKHU8PccUMHv3mXHkR?cluster=testnet
https://explorer.solana.com/tx/3kviP9MqkWGMV4yA7k7yPQ5BGfXmcYLcctmY1u2D7n56eT1nx8jMtDumkUNJy8yA3KkmzrmfQLjqpigc8ehGZzBN?cluster=testnet
https://explorer.solana.com/tx/38iEaJBzuGMLbfcszdVB8pkniezH8JrA3XGq7JdADZTQ4hNQC82GSTUA2bmcypdVy3t7htWnUzkZ4F8EakmNvqz8?cluster=testnet
3.2 Angriffstransaktion
Um die Bedeutung der Eigentümer- und Unterzeichnerprüfung zu verdeutlichen, verwenden wir zwei Angriffsszenarien als Beispiele.
Erstes Szenario
Das erste Szenario ist, dass der Eigentümer der „Tür" versucht, die Tür zu öffnen, wenn die config gesperrt ist. Dazu erstellen wir ein gefälschtes config-Konto in einem anderen Programm und weisen dem Attribut is_lock den Wert false zu. Der Code des benutzerdefinierten Programms ist unten dargestellt.
Wir senden die Transaktion, um das gefälschte Config-Konto zu erstellen. Der öffentliche Schlüssel des gefälschten Config-Kontos lautet: 2MtSrbWp24VjPZQcSUkiWrvNro7qqKemVCsh3Yxc8LTy.
https://explorer.solana.com/tx/2qSyrL5gdQXmgGCFzmzMm1StFQRkDgWpss9A9jV11q2fgDGM5C1XRuXvbX1N5Dt3q2pRqnmyXHVtXGF5dqadAzpJ?cluster=testnet
Sobald das gefälschte config-Konto erstellt wurde, schleusen wir es in das Programm ein (Zeile 423).

Das Ergebnis ist unten dargestellt: Das Protokoll gibt aus, dass incorrect program id for instruction, was bedeutet, dass der Eigentümer des config-Kontos das Programm sein muss. Daher kann der Angreifer diese Prüfung nicht umgehen.

Zweites Szenario
Das zweite Szenario ist, dass ein böswilliger Benutzer versucht, die Tür zu öffnen, wenn die Tür entsperrt ist.

In diesem Fall schleusen wir das echte Eigentümerkonto in das Programm ein (Zeile 419) und senden die Transaktion. Das Ergebnis ist unten dargestellt.

Es wird ausgegeben, dass Signature verification failed, was bedeutet, dass der echte Eigentümer die Transaktion zum Öffnen der Tür signieren muss. Daher schlägt auch unser zweiter Angriff fehl.
4. Zusammenfassung
In Solana implementieren Instruktionen spezifische Logik basierend auf verschiedenen Konten, die von Clients oder anderen Programmen bereitgestellt werden. Daher ist die ordnungsgemäße Überprüfung der Konten äußerst wichtig.
In diesem Artikel stellen wir vor, wie Konten ordnungsgemäß überprüft werden, und verwenden zwei Angriffsszenarien, um die Bedeutung dieser Überprüfungen zu verdeutlichen. Bleiben Sie dabei – weitere Artikel werden folgen.
Weitere Artikel dieser Serie lesen:
- Das Solana-Ökosystem sichern (1) — Hallo Solana
- Das Solana-Ökosystem sichern (2) — Aufrufe zwischen Programmen
- Das Solana-Ökosystem sichern (3) — Programm-Upgrade
- Das Solana-Ökosystem sichern (5) — Multi-Sig
- Das Solana-Ökosystem sichern (6) — Multi-Sig2
- Das Solana-Ökosystem sichern (7) — Typverwechslung
Über BlockSec
BlockSec ist ein wegweisendes Blockchain-Sicherheitsunternehmen, das 2021 von einer Gruppe weltweit anerkannter Sicherheitsexperten gegründet wurde. Das Unternehmen hat sich der Verbesserung von Sicherheit und Benutzerfreundlichkeit für die aufkommende Web3-Welt verschrieben, um deren breite Akzeptanz zu fördern. Zu diesem Zweck bietet BlockSec Smart-Contract- und EVM-Chain-Sicherheitsaudits, die Phalcon-Plattform für die Sicherheitsentwicklung und proaktive Bedrohungsabwehr, die MetaSleuth-Plattform für die Verfolgung und Untersuchung von Geldflüssen sowie die MetaSuites-Erweiterung für Web3-Entwickler, die effizient in der Kryptowelt navigieren möchten.
Bis heute hat das Unternehmen über 300 renommierte Kunden wie MetaMask, Uniswap Foundation, Compound, Forta und PancakeSwap betreut und in zwei Finanzierungsrunden zig Millionen US-Dollar von namhaften Investoren erhalten, darunter Matrix Partners, Vitalbridge Capital und Fenbushi Capital.
Offizielle Website: https://blocksec.com/
Offizielles Twitter-Konto: https://twitter.com/BlockSecTeam




