# Modülü bir yabancı nişanladı

> Bir Gnosis Safe, restake edilmiş ETH cinsinden 7,8 milyon dolar kaybetti — Safe bozuk olduğu için değil, etkin bir modülün, gelişigüzel bir keeper'ın onu saldırganın kendi havuzuna nişanlamasına izin verdiği için. Sınıf eski. Ders, bir hedefin nereden gelmesine izin verdiğinde.

- Source: https://defiloops.com/tr/blog/the-executor-that-trusted-itself
- Published: 2026-09-15
- Category: Security
- Tags: security, agentic-wallet, authorization, smart-accounts, restaking
- Author: DeFiLoops

---
15 Eylül 2026'da bir Ethereum kullanıcısı, çok imzalı bir cüzdandan restake edilmiş ETH
cinsinden yaklaşık **7,8 milyon dolar** kaybetti. Akılda kalıcı bir sürpriz var —bir
front-running botu parayı saldırganın kendisinden önce aldı— ama sürpriz ders değil. Ders,
ondan önceki dört saniye: cüzdanın, kendisine hiçbir şey söyleyememesi gereken biri
tarafından söylenen şeyi tam olarak yaptığı an.

Saldırının biçimi şöyle, çünkü bu bir akıllı hesabı boşaltmanın en yaygın yollarından biri ve
kusurlu kısım her zaman doğru görünür.

## Aslında ne oldu

Kurban, bir Gnosis Safe içinde, Aave ile sarmalanmış hâliyle yaklaşık 2.900 rsETH —bir likit
restaking token'ı— tutuyordu. Saldırganın hiçbir zaman bir anahtarı olmadı.

Bunun yerine, hesabın etkinleştirdiği bir Uniswap V4 likidite modülünü —**saldırganın az önce
oluşturduğu bir havuza**— nişanlamak için bir **halka açık keeper çağrısı** kullandı. O havuz
kötü niyetli bir hook taşıyordu. Hook, pozisyonu serbestçe transfer edilebilir rsETH'e açtı ve
modül, Safe'in yetkisiyle hareket ederek onu taşıdı.

<Callout type="danger" title="Kusur Safe değildi">
  Bu önemli ve insanların ilk yanlış anladığı şey bu. Gnosis Safe, çok imzalı bir cüzdanın
  yapması gerekeni yaptı: etkin bir modülün hareket etmesine izin verdi. Kusur **modülde**
  idi —Safe'in üstüne kurulmuş, çağıranından bir hedef kabul eden üçüncü taraf bir sözleşme.
  Cüzdanı suçlamak, hatanın yaşadığı yeri ıskalar; ve bu hata, herhangi bir hesap çatısında
  herkesin tekrarlayabileceği bir hata.
</Callout>

## Kusur, hedefin nereden geldiğinde

Restaking'i ve hook'ları çıkarın, geriye tek bir madde kalır. Güvenilir bir modüle, çağıranı
tarafından bir hedef —hangi havuz, hangi sözleşme— verildi ve modül bu hedefe kendi ayrıcalıklı
bağlamının içinden hareket etti. Yaptığı doğrulama yetmiyordu, çünkü saldırgan paranın nereye
gideceğine karar veren tek şeyi seçebiliyordu.

<Compare left="Modülün çağırana sağlattığı şey" right="Bir çağıranın asla sağlamaması gereken şey" verdict>
  <Fragment slot="left">
    Yönlendirilecek havuz. Çağrı anında, herkesin çağırabileceği halka açık bir keeper
    tarafından seçilen bir sözleşme adresi.
  </Fragment>
  <Fragment slot="right">
    Bir hedefe karar veren hiçbir şey. Mekân, sahibin kurduğu bir listeden adlandırılır; alıcı
    her zaman hesaptır; çağrıyı modül oluşturur.
  </Fragment>
</Compare>

Hedefini çağıranından alan bir modül, çağıranın onu doğru nişanlayacağına güvenen bir modüldür.
Halka açık bir keeper yolunda ise çağıran halktır. Saldırgan zorla girmedi. Direksiyon eline
verildi ve kibar olması rica edildi.

## Sürpriz, güzel olduğu için

Exploit işlemi halka açık mempool'a —onaylanmamış işlemlerin açıkta beklediği bekleme
odasına— girdi. Yoink adında genelleştirilmiş bir front-running botu bekleyen boşaltmayı
gördü, daha yüksek bir ücretle kopyaladı ve aynı blokta önce çalıştırdı. Asıl saldırgan
hiçbir şey alamadı.

<Callout type="warn" title="Bir fiyatına iki başarısızlık">
  Cüzdan boşaltılabilirdi, çünkü bir yabancı bir modülü nişanlayabiliyordu. *Saldırgan*
  soyuldu, çünkü değerli bir işlem yayınlandığı an herkes tarafından görülebilir. Kurban
  parayı her hâlükârda kaybetti. Halka açık bir zincirde, ilk olmak, işlemi başlatan olmaktan
  daha çok önemlidir — ki bu da bir boşaltmayı, herkesin sahiplenmesi için mempool'da bekletmemenin
  bir başka nedeni.
</Callout>

## Bu bir DeFiLoops hesabında olabilir mi?

Bizim yerimizdeki bir okuyucunun gerçekten sorduğu soru bu, o yüzden dürüst cevap şu: **belirli
hamle —güvenilir bir modülü bir saldırganın sözleşmesine nişanlamak— bir DeFiLoops hesabına
karşı ifade edilemez; şansla değil, tasarımla.** Kontrollerimiz daha özenli olduğu için değil.
Çünkü ajana nişanlayacağı bir hedef hiçbir zaman verilmez.

<Spec title="Saldırganın girdilerinin gidecek yerinin olmadığı yer" rows={[
  ['Yönlendirilecek havuzu / sözleşmeyi seçmek', 'Öyle bir alan yok. Ajan tipli parametreler verir; adaptör çağrıyı oluşturur ve hedefi seçer.'],
  ['Bir mekânı adresle adlandırmak', 'Reddedilir. Mekânlar sahibin kurduğu kümeden adlandırılır, asla talimattaki bir adres olarak değil.'],
  ['Ödemeyi kendine yönlendirmek', 'Alıcı hesaba zorlanır, hesaptan okunur — asla talimattan alınmaz.'],
  ['Bu hesabı kastettiğini kanıtlamak', 'Sahip hesaptan okunur. Ajanın geçerli bir imzası, doğru hesabın ya da doğru hedefin kastedildiğinin kanıtı değildir.'],
]} />

Daha derin neden bir seviye yukarıda. **Üretimdeki bir DeFiLoops hesabı ajana hiçbir doğrudan
çağrı yolu vermez.** Boşaltılan Safe'in, çağıran tarafından seçilen bir çağrıyı çalıştırabilen
bir modülü vardı. Bizim ajanımız bir çağrı oluşturamaz. Bir miktar, listeden adlandırılmış bir
mekân, bir aralık verir — ve beyaz listedeki bir adaptör işlemi kurar. Sağlanan bir sözleşme
yoktur, çünkü ajan hiçbir zaman bir tane sağlamaz.

<StatRow>
  <Stat value="0 $" label="saldırganın seçtiği bir hedefin taşıyabileceği" accent />
  <Stat value="0" label="üretimde ajan için doğrudan çağrı yolu" />
  <Stat value="1" label="ajanı tamamen iptal etmek için işlem" />
</StatRow>

## Saldırganın planı, adım adım

Sahip anahtarını çalmak dışındaki en güçlü gerçekçi saldırganı varsayın: elinde *ajan*
anahtarı var, yani hesabın günlük talimatlarını imzalayan anahtar. Deneyeceği şey ve her
adımın nerede bittiği şöyle.

<Steps>
  <Step title="Bir modülü kontrol ettiğin bir havuza nişanla">
    Çağıranından havuz alan bir modül yok. Ticaret, mekânı sahibin kurduğu kümeden okuyan
    adaptörlerden geçer. Saldırganın oluşturduğu bir havuz o kümede değildir ve talimattaki bir
    adres keyfî bir çağrı olarak reddedilir.
  </Step>
  <Step title="Doğrudan bir çağrıya geri dön ve kendi hedefini seç">
    Üretimde geri dönülecek bir doğrudan çağrı yolu yok. Kurulu değil. Hamlenin yazılacağı bir
    yer yok.
  </Step>
  <Step title="Meşru bir adaptörden geç ve fonları yönlendir">
    Alıcı hesaba zorlanır, sahip hesaptan okunur, mekân sahibin kümesinden gelir ve harcama
    dönem başına sınırlıdır. Her hedefi talimat değil, adaptör belirler.
  </Step>
  <Step title="Kendi modülünü kur ya da hesabın kökünü değiştir">
    O seçiciler reddedilir. Ajan, Safe'i boşaltan türden yeniden yönlendirilebilir bir modülü
    asla kuramaz, sahip olamaz ya da hesabı devredemez.
  </Step>
  <Step title="Bu sırada sahip ajanı iptal eder">
    Kimsenin iş birliğini gerektirmeyen tek bir işlem; ve o anahtardan gelen her gelecekteki
    talimat, hedefi incelenmeden önce reddedilir. Çalınan anahtar, sahip harekete geçtiği an
    ölür.
  </Step>
</Steps>

Çalınmış bir ajan anahtarı, üretimdeki bir hesaba karşı, hiçbir şeyi bir saldırgana nişanlayamaz
ve kontrolü ele geçiremez. Güvenlik iddiasının tamamı bu ve tam da bu saldırıya karşı geçerli.

## Neyi iddia etmiyoruz

Orada biten bir güvenlik yazısı bir şey satıyordur. Dürüst sınırın üç kenarı var ve hiçbiri
*bu* saldırı değil.

<Callout type="warn" title="Kalan riskler, adlarıyla">
  **Sahip anahtarın.** Onu tutan her şeyi yapabilir —modül kurar, kökü değiştirir. Her akıllı
  hesap için geçerli ve hiçbir tasarım bunu kapatmaz. O anahtarı koru.

  **Geliştirme modu.** Fork'larda, gerçek bir zincire karşı test edebilmek için daha zayıf bir
  kurallar kümesinin arkasında bir doğrudan çağrı yolu vardır. Üretimde başlangıçta reddedilir.
  Eğer bir gün üretime ulaşsaydı, değer yüzeyi açılırdı.

  **Adaptör disiplini.** Modelin tamamı, *her* adaptörün hedefi ve alıcıyı kendisinin
  sabitlemesine dayanır. Talimattan bir hedef alan bir adaptör, tam da Safe'i boşaltan yeniden
  yönlendirilebilir modül olurdu. Her adaptörü aynı kontrol listesine tabi tutuyoruz ve her
  birini, alıcıyı bir saldırgana nişanlayıp iddianın başarısız olmasını izleyen bir testle
  kanıtlıyoruz.
</Callout>

## Kendi güvenimizi değiştiren kısım

Guard'ın bunu engellediğini kanıtlamaya koyulduk. O kanıtı yazmak, hâlihazırda sahip olduğumuz
testlerin bunu kanıtlamadığını ortaya çıkardı — bir katman erken, hesabın tesisatında revert
ediyorlardı ve test çatısı yanlış revert'i gevşek eşleştirdiği için geçiyorlardı. Koruma
gerçekti. Ona dair kanıt ise tiyatroydu.

<Quote>
  Koruduğu şeyi kırdığında başarısız olamayan bir güvenlik testi zayıf bir test değildir. Bir
  süstür ve hiç test olmamasından daha tehlikelidir, çünkü kapsam gibi okunur.
</Quote>

Bu yüzden kanıtı doğrudan guard'a karşı yeniden kurduk, her çağrının reddedilmesinin tam
nedenini iddia ederek; sonra her kontrolü kasten kırıp ilgili testin başarısız olmasını
izledik. Öz-referans satırını kaldırmak kendi testini düşürüyor. İptal yolunu etkisizleştirmek
bir başkasını düşürüyor. Bir sınırın tuttuğuna inanmak ile bunu bilmek arasındaki fark budur.

## Böyle bir iddiayı nasıl değerlendirmeli

Bu sayfaya güvenmek zorunda değilsin. Gerçek bir sınırı bir filtreden ayıran soru her zamanki
soru: **ajan, ya da geçmekte olan bir keeper, neyi yazabilir?**

Cevap bir hedef içeriyorsa —bir havuz, bir sözleşme, çağıranın seçtiği bir adres— o zaman
etrafındaki her koruma, bir yabancının seçtiği hedef ile paranın arasında duran bir kontroldür
ve kontroller, birilerinin daha önce hayal ettiği saldırılara karşı yargılanır. Eylül
boşaltması, çağıranın seçtiği bir hedefin bedelidir.

Cevap *tipli parametreler ve başka hiçbir şey* ise, bu yazıdaki saldırının ineceği bir yer
yoktur, çünkü sömürdüğü şey —adlandırabileceğin bir hedef— hiçbir zaman verilmemiştir.

---

*Kaynaklar: PeckShieldAlert ve Blockaid izleme raporları (15 Eylül 2026), PANews, Odaily,
Foresight News ve BlockBeats tarafından aktarıldı; zincir üstü işlemler Etherscan üzerinden.
Rakamlar ve mekanizma o an raporlandığı şekildedir ve analiz ilerledikçe revize edilebilir.*