
Blindes Signieren: was du tatsächlich freigibst, wenn der Bildschirm nichts Brauchbares sagt
Es gibt einen bestimmten Moment, in dem die meisten großen Krypto-Verluste passieren. Nicht, wenn ein Schlüssel gestohlen wird. Sondern wenn jemand auf eine Signaturabfrage schaut, die er nicht versteht, entscheidet, dass es schon in Ordnung sein wird, und auf Freigeben tippt.
Die Branche hat einen Namen dafür: blindes Signieren. Es bedeutet, seine Unterschrift unter Daten zu setzen, die man nicht lesen kann. Und jahrelang behandelten Wallets das als normal.
Was ein Signaturbildschirm leisten soll
Das Sicherheitsversprechen der Selbstverwahrung ruht auf einer Annahme: dass sich nichts ohne deine Freigabe bewegt. Zwei-von-zwei-Multisig, Hardware-Wallets, luftspaltgetrennte Signierer — jedes davon ist eine Maschine, die deine Absicht in eine Signatur verwandelt.
Diese Maschinerie ist genau so viel wert wie dein Verständnis dessen, was du freigegeben hast.
Wenn der Bildschirm sagt „Sende 0,5 ETH an 0x8f3C…", bedeutet deine Freigabe etwas. Du hast sie mit dem verglichen, was du vorhattest. Wenn der Bildschirm sagt „Contract-Interaktion — Daten: 0xa22cb465000000000000000000000000d8dA6…0001", bedeutet deine Freigabe überhaupt nichts. Du stimmst keiner Transaktion zu; du stimmst einem Rechteck aus Hexadezimalzeichen zu.
Angreifer wissen, welchen dieser beiden Bildschirme du sehen sollst.
Was sich in den Bytes versteckt
Die Nutzlast einer EVM-Transaktion sind Calldata: ein Vier-Byte-Funktionsselektor, gefolgt von ABI-kodierten Argumenten. Für eine Maschine perfekt lesbar, für einen Menschen perfekt undurchsichtig. Eine Handvoll dieser Selektoren ist der Weg, auf dem das Geld verschwindet.
approve(address,uint256) — Selektor 095ea7b3. Erteilt einem Contract die Erlaubnis, deine Token auszugeben. Keine Überweisung, sondern eine dauerhafte Ermächtigung. Beim Signieren bewegt sich nichts, und genau deshalb rutscht sie durch. Das Leerräumen passiert später, nach dem Zeitplan des Angreifers.
setApprovalForAll(address,bool) — Selektor a22cb465. Das NFT-Äquivalent, und schlimmer: Eine Signatur gibt einem Operator Befugnis über jeden Token dieser Sammlung, den du hältst, jetzt und künftig. Es gibt kein Betragsfeld, an dem man sich beruhigen könnte.
increaseAllowance(address,uint256) — Selektor 39509351. Stockt eine bestehende Erlaubnis auf. Wird oft übersehen, weil es nicht der Selektor ist, auf den alle achten sollten.
transferFrom(address,address,uint256) — Selektor 23b872dd. Bewegt Token von einer Adresse, die bereits eine Erlaubnis erteilt hat. Die Signatur, die endlich ausgibt, was ein früheres approve genehmigt hat.
Das Muster, das man verinnerlichen sollte: Die Transaktion, die dein Geld stiehlt, ist selten die Transaktion, die du signiert hast. Du hast eine Erlaubnis signiert. Der Diebstahl ist eine eigene, später gesendete Transaktion, die du nie zu Gesicht bekommst.
Warum „unbegrenzt" das entscheidende Wort ist
Fast jeder Allowance-Exploit teilt ein Merkmal: Der Betrag ist praktisch unendlich.
Dapps verlangen unbegrenzte Freigaben, weil es bequem ist — einmal genehmigen, nie wieder gefragt werden. Das Ergebnis: Nutzer werden darauf trainiert, routinemäßig unbegrenzte Ausgaberechte zu erteilen, und eine Oberfläche, die 115792089237316195423570985008687907853269984665640564039457584007913129639935 anzeigt, sagt niemandem irgendetwas.
Es gibt eine Feinheit, an der naive Implementierungen scheitern. Der kanonische Wert für „unendliche Freigabe" ist exakt 2²⁵⁶−1, also liegt der Vergleich mit dieser Konstante nahe. Doch Dapps benutzen regelmäßig andere astronomisch große Zahlen — die Hälfte des Maximums, 0xff…f0, 10¹⁸ × 10³⁸ —, die in jedem praktischen Sinn unbegrenzt sind und trotzdem an einem Exakt-Vergleich vorbeirutschen. Eine Warnung, die nur beim genauen Sentinel auslöst, ist eine Warnung, um die ein Angreifer herumkommt, indem er eins abzieht.
Die richtige Schwelle liegt deutlich unter dem Sentinel und deutlich über allem Realen. SSP markiert jede Allowance ab 2²⁵⁵ — rund 5,8 × 10⁷⁶, was jeden möglichen ERC-20-Bestand um Dutzende Größenordnungen übersteigt. Nichts Legitimes wird je fälschlich markiert, und ein knapp unter dem Maximum getrimmter Wert umgeht die Warnung nicht.
Diese Schwelle gilt nur für Aufrufe, die Allowances erteilen. Bei einer schlichten Überweisung ist „unbegrenzt" kein sinnvoller Begriff — du bewegst einen bestimmten Betrag —, also bleibt der Exakt-Maximum-Sentinel dort unangetastet.
Was SSP tut
SSP dekodiert Calldata auf dem Freigabebildschirm in Klartext. Erkannte Selektoren werden als das dargestellt, was sie sind: wer die Gegenpartei ist, wie hoch der Betrag ist, ob die erteilten Rechte unbegrenzt sind. Roher Hex ist nicht mehr der Hauptinhalt — er liegt hinter einem Bereich „Erweitert" für alle, die ihn sehen wollen.
Drei Designentscheidungen zählen mehr als das Dekodieren selbst.
Der Dekoder ist reine Darstellung. Er ändert nie, was signiert wird. Die Freigabe signiert stets exakt die ursprüngliche Nutzlast; der Helfer stellt nur Bytes neu dar, die zuvor als roher Hex gezeigt wurden. Ein Dekoder, der die Nutzlast verändern könnte, wäre eine neue Angriffsfläche statt einer Verteidigung — das Gelesene und das Signierte müssen immer dieselben Bytes sein.
Er scheitert nach innen. Unbekannter Selektor, falsche Länge, fehlerhafter Hex, nicht standardkonforme Adresspolsterung — alles Unerwartete liefert nichts zurück, und die Oberfläche fällt auf eine generische Aktion mit rohem Hex unter „Erweitert" zurück. Er rät nie. Ein ratender Dekoder ist schlimmer als gar keiner, denn eine selbstsichere falsche Zusammenfassung ist gefährlicher als sichtbarer Hex: Hex sagt dir wenigstens ehrlich, dass du ihn nicht verstehst.
Dieser Fail-Closed-Instinkt reicht tiefer als unbekannte Funktionen. Eine ABI-kodierte Adresse besteht aus zwölf Nullbytes und zwanzig Adressbytes; ein Wort mit irgendetwas anderem in diesen führenden Bytes ist nicht kanonisch kodiert, und SSP behandelt es als verdächtig, statt es zu deuten. Dasselbe bei Booleans — akzeptiert werden nur die kanonischen Kodierungen: alles Null (falsch) und 31 Nullen plus 0x01 (wahr). Nicht kanonische Kodierungen auf einem Bildschirm, der Ausgaberechte erteilt, sind ein Warnsignal, keine Parsing-Aufgabe.
Token-Symbole und Dezimalstellen werden nie geraten. Ein menschlich lesbarer Betrag erscheint nur, wenn der Token aus dem Verzeichnis auf dem Gerät zuverlässig bekannt ist. Sonst siehst du die rohe Zahl in Basiseinheiten. Das ist bewusst weniger hübsch: „5,0 USDC" für einen Contract anzuzeigen, der sich lediglich USDC nennt, würde den Dekoder in eine Lügenmaschine verwandeln — genau das Ergebnis, das ein Angreifer will.
Und dann gibt es den Teil, der strukturell statt kosmetisch ist. In SSP wird die Transaktion an einem Ort gebaut und an einem anderen freigegeben: zusammengestellt in der Browsererweiterung, unabhängig dekodiert und angezeigt auf deinem Telefon, wo SSP Key den Transaktionshash auf dem Gerät neu berechnet und die Signatur verweigert, wenn er nicht zum Angezeigten passt. Blindes Signieren auf einem einzigen Gerät heißt, dass ein kompromittierter Bildschirm genügt. Hier sind der Bildschirm, der dir die dekodierte Aktion zeigt, und das Gerät mit dem zweiten Schlüssel dasselbe Gerät — und es prüft, statt zu vertrauen.
Was du mit deinen eigenen Freigaben tun solltest
Behandle approve und setApprovalForAll als die gefährlichen. Es sind die Signaturen, die Menschen Geld kosten, und sie wirken harmlos genau deshalb, weil sich nichts bewegt.
Lehne unbegrenzte Freigaben ab, wo du kannst. Viele Dapps akzeptieren einen begrenzten Betrag, wenn du einen setzt. Das ist Reibung — und deckelt deinen Verlust auf das, was du tatsächlich ausgeben wolltest.
Prüfe, was du bereits erteilt hast. Alte Freigaben laufen nicht ab. Eine Erlaubnis, die du einem Protokoll vor zwei Jahren gegeben hast, ist noch aktiv, und wird dieser Contract später kompromittiert, ist sie ein offener Weg zu deinen Token. Freigaben zu widerrufen geht schnell und ist die wertvollste Aufräumstunde der Selbstverwahrung.
Wenn der Bildschirm dir nichts sagt, ist genau das das Signal. Kann deine Wallet nicht sagen, was eine Transaktion tut, ist das eine Information — keine Unbequemlichkeit, durch die man sich klickt. Die richtige Antwort auf eine unlesbare Abfrage ist anzuhalten, nicht die Augen zusammenzukneifen.
Das Ziel war nie, dass du Hex liest. Es ist, dafür zu sorgen, dass du und deine Wallet sich einig sind, was du da freigibst.


