Kör imzalama: ekran işe yarar bir şey söylemediğinde aslında neyi onaylıyorsunuz

·6 dk okuma·Yazar: SSP Editorial Team
SSP Academy kapağı: kör imzalama ve okunamayan işlem onayları

Kör imzalama: ekran işe yarar bir şey söylemediğinde aslında neyi onaylıyorsunuz

Büyük kripto kayıplarının çoğunun yaşandığı belirli bir an vardır. Bir anahtarın çalındığı an değil. Birinin anlamadığı bir imza istemine bakıp muhtemelen sorun yoktur diye karar verdiği ve onayla düğmesine dokunduğu andır.

Sektörün buna bir adı var: kör imzalama. Okuyamadığınız verilerin altına imzanızı atmak demek. Ve yıllarca cüzdanlar bunu olağan saydı.

Bir imza ekranının yapması gereken

Kendi kendine saklamanın güvenlik vaadi tek bir varsayıma dayanır: sizin onayınız olmadan hiçbir şeyin kıpırdamayacağı. İki-of-iki çoklu imza, donanım cüzdanları, hava boşluklu imzalayıcılar — hepsi niyetinizi bir imzaya dönüştüren birer makinedir.

Bu makine tam olarak, onayladığınız şeyi ne kadar anladığınız kadar değerlidir.

Ekran "0x8f3C… adresine 0,5 ETH gönder" diyorsa, onayınız bir anlam taşır. Onu yapmak istediğiniz şeyle karşılaştırdınız. Ekran "Sözleşme etkileşimi — veri: 0xa22cb465000000000000000000000000d8dA6…0001" diyorsa, onayınız hiçbir şey ifade etmez. Bir işleme rıza göstermiyorsunuz; bir onaltılık dikdörtgene rıza gösteriyorsunuz.

Saldırganlar bu iki ekrandan hangisini görmenizi istediklerini bilir.

Baytların içinde ne saklanır

Bir EVM işleminin yükü calldata'dır: dört baytlık bir işlev seçicisi ve ardından ABI ile kodlanmış argümanlar. Bir makine için kusursuzca okunabilir, bir insan için kusursuzca kapalı. Paranın çıktığı yol, o seçicilerden bir avuç kadarıdır.

approve(address,uint256) — seçici 095ea7b3. Bir sözleşmeye jetonlarınızı harcama izni verir. Transfer değil; kalıcı bir yetkilendirme. İmzaladığınızda hiçbir şey kıpırdamaz, tam da bu yüzden fark edilmeden geçer. Boşaltma sonra, saldırganın takvimine göre olur.

setApprovalForAll(address,bool) — seçici a22cb465. NFT karşılığı, ve daha kötüsü: tek bir imza, o koleksiyonda sahip olduğunuz her jeton üzerinde bir operatöre yetki verir; şimdi ve gelecekte. İçinize su serpecek bir tutar alanı yoktur.

increaseAllowance(address,uint256) — seçici 39509351. Var olan bir izni takviye eder. Herkese dikkat edin denen seçici olmadığı için sıkça gözden kaçar.

transferFrom(address,address,uint256) — seçici 23b872dd. Daha önce izin vermiş bir adresten jeton taşır. Önceki bir approve çağrısının yetki verdiği şeyi nihayet harcayan imzadır.

İçselleştirmeye değer örüntü şu: paranızı çalan işlem, nadiren imzaladığınız işlemdir. Siz izin imzaladınız. Hırsızlık, sonradan gönderilen ve sizin hiç görmediğiniz ayrı bir işlemdir.

Neden aranacak kelime "sınırsız"

Neredeyse bütün izin istismarlarının ortak bir özelliği vardır: tutar fiilen sonsuzdur.

Dapp'ler sınırsız onay ister, çünkü rahattır — bir kez onaylayın, bir daha sorulmasın. Sonuç şu: kullanıcılar sınırsız harcama hakkını alışkanlıkla vermeye alıştırılır ve 115792089237316195423570985008687907853269984665640564039457584007913129639935 gösteren bir arayüz kimseye hiçbir şey söylemez.

Toy uygulamaları yakalayan bir incelik var. "Sonsuz onay"ın kanonik değeri tam olarak 2²⁵⁶−1'dir, dolayısıyla bariz denetim bu sabitle karşılaştırmaktır. Ama dapp'ler rutin olarak başka astronomik sayılar kullanır — azaminin yarısı, 0xff…f0, 10¹⁸ × 10³⁸ — ki bunlar her pratik anlamda sınırsızdır, yine de tam eşitlik testinden kaçar. Yalnızca tam nöbetçi değerde tetiklenen bir uyarı, saldırganın birer eksilterek etrafından dolaşabildiği bir uyarıdır.

Doğru eşik, nöbetçi değerin epey altında ve gerçek olan her şeyin epey üstündedir. SSP, 2²⁵⁵ ve üzerindeki her izni işaretler — kabaca 5,8 × 10⁷⁶, ki bu mümkün olan her ERC-20 arzını onlarca büyüklük mertebesi aşar. Meşru hiçbir şey yanlışlıkla işaretlenmez ve azaminin hemen altına ayarlanmış bir değer uyarıyı atlatamaz.

Bu eşik yalnızca izin veren çağrılara uygulanır. Düz bir transferde "sınırsız" anlamlı bir fikir değildir — belirli bir tutarı taşıyorsunuz — dolayısıyla orada tam azami nöbetçi değere dokunulmaz.

SSP ne yapıyor

SSP, onay ekranında calldata'yı sade dile çevirir. Tanınan seçiciler gerçekte ne iseler öyle gösterilir: karşı taraf kim, tutar ne, verilen haklar sınırsız mı. Ham onaltılık artık ana içerik değil; isteyenler için Gelişmiş bölümünün arkasında yaşıyor.

Üç tasarım kararı, çözümlemenin kendisinden daha çok önem taşıyor.

Çözücü yalnızca sunum katmanıdır. İmzalananı asla değiştirmez. Onay her zaman özgün yükün tam olarak kendisini imzalar; yardımcı yalnızca daha önce ham onaltılık olarak gösterilen baytları yeniden sunar. Yükü değiştirebilecek bir çözücü, savunma değil yeni bir saldırı yüzeyi olurdu — okuduğunuz ile imzaladığınız her zaman aynı baytlar olmalıdır.

Kapanarak başarısız olur. Bilinmeyen seçici, yanlış uzunluk, bozuk onaltılık, standart dışı adres dolgusu — beklenmedik her şey hiçbir şey döndürmez ve arayüz, Gelişmiş içinde ham onaltılığın bulunduğu genel bir eyleme geri düşer. Asla tahmin yürütmez. Tahmin yürüten bir çözücü, hiç çözücü olmamasından kötüdür; çünkü kendinden emin ve yanlış bir özet, görünür onaltılıktan daha tehlikelidir: onaltılık en azından onu anlamadığınızı dürüstçe söyler.

Bu kapanarak başarısız olma içgüdüsü bilinmeyen işlevlerden daha derine iner. ABI ile kodlanmış bir adres, on iki sıfır bayt ve ardından yirmi adres baytıdır; o baştaki baytlarda başka bir şey bulunan bir sözcük kanonik kodlanmamıştır ve SSP onu yorumlamaya çalışmak yerine şüpheli sayar. Mantıksal değerlerde de aynısı — yalnızca kanonik kodlamalar kabul edilir: tümü sıfır (yanlış) ve 31 sıfırın ardından 0x01 (doğru). Harcama hakkı veren bir ekranda kanonik olmayan kodlamalar, bir ayrıştırma bilmecesi değil, kırmızı bayraktır.

Jeton simgeleri ve ondalıkları asla tahmin edilmez. İnsan okuyabilir bir tutar yalnızca, jeton cihazdaki kayıttan güvenle bilindiğinde gösterilir. Aksi hâlde temel birimlerdeki ham sayıyı görürsünüz. Bu bilerek daha az şık: yalnızca kendine USDC diyen bir sözleşme için "5,0 USDC" göstermek, çözücüyü bir yalan makinesine dönüştürürdü ki saldırganın istediği tam olarak budur.

Bir de kozmetik değil yapısal olan kısım var. SSP'de işlem bir yerde kurulur, başka bir yerde onaylanır: tarayıcı eklentisinde derlenir, telefonunuzda bağımsız olarak çözülür ve gösterilir; orada SSP Key işlem özetini cihaz üzerinde yeniden hesaplar ve gösterilenle uyuşmuyorsa imzalamayı reddeder. Tek cihazda kör imzalama, ele geçirilmiş tek bir ekranın yeteceği anlamına gelir. Burada, çözülmüş eylemi size gösteren ekran ile ikinci anahtarı tutan cihaz aynı cihazdır ve o cihaz güvenmek yerine doğrular.

Kendi onaylarınızla ne yapmalı

approve ve setApprovalForAll'ı tehlikeli olanlar sayın. İnsanlara para kaybettiren imzalar bunlardır ve zararsız görünmelerinin nedeni tam da hiçbir şeyin kıpırdamamasıdır.

Yapabildiğinizde sınırsız onayları reddedin. Birçok dapp, siz belirlerseniz sınırlı bir tutarı kabul eder. Bu bir sürtünmedir ve kaybınızı gerçekten harcamayı düşündüğünüz miktarla sınırlar.

Daha önce verdiklerinizi gözden geçirin. Eski onaylar sona ermez. İki yıl önce bir protokole verdiğiniz izin hâlâ canlıdır ve o sözleşme sonradan ele geçirilirse jetonlarınıza açık bir yol olur. Onayları geri almak hızlıdır ve kendi kendine saklamada en yüksek getirili temizlik saatidir.

Ekran size hiçbir şey söylemiyorsa, işaret budur. Cüzdanınız bir işlemin ne yaptığını söyleyemiyorsa, bu bir bilgidir — tıklayarak geçilecek bir zahmet değil. Okunamayan bir isteme doğru yanıt gözleri kısmak değil, durmaktır.

Amaç hiçbir zaman size onaltılık okutmak değildi. Amaç, bir şeyi onayladığınızda, onun ne olduğu konusunda sizin ve cüzdanınızın hemfikir olmasıdır.

Bu makaleyi paylaş

İlgili makaleler