Mono Audit logo

Yaygın Zafiyetler Listesi

Akıllı sözleşme zafiyetleri, dağıtıldıktan sonra yıkıcı ve genellikle geri döndürülemez sonuçlara yol açabilir. Bu zayıflıkların istismar edilmesi, blok zinciri güvenliği için büyük bir zorluk teşkil etmekte, milyarlarca dolarlık varlığın çalınmasına ve kullanıcı güveninin sarsılmasına neden olmaktadır. Bu nedenle, sağlam akıllı sözleşme güvenliği sağlamak hayati önem taşımaktadır. Bu, sadece kodu blok zincirine dağıtmaktan daha fazlasını gerektirir. Sıkı güvenli kodlama uygulamaları, kapsamlı testler ve genellikle sorunları istismar edilmeden önce belirlemek için bağımsız akıllı sözleşme denetimleri gerektirir. Kötü şöhretli DAO hack'i gibi yeniden giriş saldırılarından, ince mantık hatalarına ve tamsayı taşmaları gibi Ethereum zafiyetlerine kadar yaygın tuzakları anlamak, riskleri azaltmaya yönelik ilk kritik adımdır. Bu sayfa, farkındalığı artırmak ve merkeziyetsiz ekosistemde daha güvenli geliştirmeyi teşvik etmek amacıyla sık karşılaşılan akıllı sözleşme zafiyetlerine temel bir bakış sunmaktadır.

  1. Reentrancy
  2. Unexpected Ether
  3. DoS
  4. Overflow
  5. tx.origin Authentication
  6. Access Control
  7. Weak Randomness
  8. Hash Collision
  9. Precision Loss
  10. msg.value in loop
  11. ecrecover
  12. Replay
  13. Inheritance Order
  14. MEV
Link

Reentrancy

Yeniden girilebilirlik (Reentrancy), The DAO saldırısı gibi önemli tarihsel istismarlara yol açan ve bir Ethereum hard fork'una neden olan, en eski ve en yıkıcı akıllı sözleşme güvenlik açıklarından biridir. Sözleşmelerin tüm fonlarını boşaltma potansiyeline sahip, korkunç sonuçları olabilecek kritik bir tehdit olmaya devam etmektedir.

Bu güvenlik açığı, genellikle Web2 alışkanlıklarından taşınan yaygın bir kodlama anti-deseninden kaynaklanır: sözleşmenin dahili durumunu (örneğin, kullanıcı bakiyeleri) güncellemeden önce harici etkileşimleri (Ether transfer etmek veya başka bir sözleşmeyi çağırmak gibi) gerçekleştirmek. Bir sözleşme Ether gönderdiğinde veya harici bir sözleşmeyi çağırdığında, yürütme kontrolünü geçici olarak devreder. Alıcı sözleşmeyi kontrol eden bir saldırgan, genellikle Ether transferiyle tetiklenen receive veya fallback fonksiyonu aracılığıyla ya da token standardı hook'ları (kancaları) üzerinden orijinal sözleşmeye hemen geri çağrı yaparak bunu istismar edebilir.

Orijinal sözleşmenin durumu (örneğin, saldırganın bakiyesi) henüz güncellenmediği için, yeniden girilebilir çağrı ilk kontrolleri geçer ve saldırganın aynı işlem içinde eylemi (fon çekme gibi) birden çok kez tekrarlamasına olanak tanır. Bu özyinelemeli döngü, fonlar tükenene veya gas limitlerine ulaşılana kadar devam eder.

Klasik saldırı tek bir fonksiyonu içerse de, fonksiyonlar arası yeniden girilebilirlik (fonksiyonlar arasındaki paylaşılan durumu istismar etme) ve salt okunur yeniden girilebilirlik (view fonksiyonları aracılığıyla durum okumalarını manipüle etme) gibi daha karmaşık varyasyonları mevcuttur.

Birincil savunma yöntemi Checks-Effects-Interactions (CEI) desenidir: Gerekli tüm kontrolleri yapın, ardından durum değişkenlerini güncelleyin (etkiler) ve yalnızca bu güncellemelerden sonra harici sözleşmelerle etkileşim kurun.

Link

Unexpected Ether

"Beklenmedik Ether Alımı Yoluyla Bakiye Manipülasyonu" zafiyeti, Solidity akıllı sözleşmelerinin, tanımlanmış `receive` ve `fallback` fonksiyonlarını atlayan mekanizmalar aracılığıyla Ether alabilmesi nedeniyle ortaya çıkar. Bu "beklenmedik" Ether enjeksiyonunun başlıca yöntemleri, kendini imha eden bir sözleşmenin bakiyesini zorla belirlenmiş bir adrese aktaran `selfdestruct` işlem kodu (opcode) ve coinbase işlemleridir (blok ödülleri).

Temel sorun, bu zorunlu transferlerin, sözleşmenin gelen fonların işlenmesi için programlanmış mantığını tetiklemeden doğrudan sözleşmenin Ether bakiyesini (`address(this).balance`) artırmasıdır. Bu durum, yaygın, genellikle üstü kapalı bir varsayımı veya değişmezi (invariant) bozar: sözleşmenin gerçek bakiyesinin, amaçlanan `payable` fonksiyonları aracılığıyla işlenen veya dahili olarak hesaba katılan fonların toplamını doğru bir şekilde yansıttığı varsayımı.

Kritik mantık kontrolleri için `address(this).balance`'ı yanlış kullanan sözleşmeler zafiyete açık hale gelir. Örneğin, sözleşmeler `address(this).balance == beklenenMiktar` kontrolünü yapabilir. Bir saldırgan, küçük bir miktar Ether göndermek için `selfdestruct` kullanarak bunu istismar edebilir ve böylece bakiyeyi manipüle edebilir. Bu durum şunlara yol açabilir:

Hizmet Reddi (DoS): Kesin eşitlik kontrolleri kalıcı olarak işlevsiz hale getirilebilir, bu da fonksiyonları kullanılamaz kılar.

Mantık Manipülasyonu: Eşik değerlere vaktinden önce ulaşılabilir, bu da istenmeyen durum değişikliklerini veya ödemeleri tetikler.

`assert` İhlalleri: Nadir durumlarda, beklenmedik bakiye, `assert()`'ün başarısız olmasına neden olan dahili durum tutarsızlıklarına yol açabilir ve tüm işlem gazını tüketebilir.

Temel önlem, sözleşme mantığı için asla `address(this).balance`'a güvenmemektir. Bunun yerine, sözleşmeler özel durum değişkenleri kullanarak doğru bir dahili muhasebe tutmalı ve bunları yalnızca meşru fon işleme fonksiyonları içinde güncellemelidir. Tüm kritik kontroller ve durum geçişleri bu güvenilir dahili değişkenlere dayanmalıdır.

Link

DoS

Solidity akıllı sözleşmelerindeki Hizmet Reddi (Denial of Service, DoS) güvenlik açıkları, sözleşmenin amaçlanan işlevselliğini aksatmayı veya tamamen durdurmayı hedefler, böylece meşru kullanıcıların hizmetlerine erişmesini engeller. Reddedilen "hizmet", sözleşmenin işlevlerini programlandığı ve kullanıcıları tarafından beklendiği şekilde yürütme yeteneğidir.

Saldırganlar bunu, sözleşmenin kod mantığındaki kusurları istismar ederek, kaynak sınırlamalarını (öncelikle gas) manipüle ederek veya harici bağımlılıklardan yararlanarak başarır.

Yaygın kalıplar şunları içerir:

Gas Tükenmesi (Gas Exhaustion): Fonksiyon yürütme maliyetlerinin blok gas limitini veya işlem gas limitini aşmasını sağlamak için işlemler oluşturmak veya durumu manipüle etmek. Bu genellikle hesaplama açısından pahalı işlemleri tetiklemeyi veya çok yaygın olarak, boyutu süresiz olarak büyüyebilen sınırsız diziler üzerinde döngü yapmayı içerir. Veri büyüdükçe, döngünün gas maliyeti limitleri aşar ve fonksiyonu kullanılamaz hale getirir.

Beklenmeyen Geri Almalar (Unexpected Reverts): Kritik fonksiyonların beklenmedik şekilde geri alınmasına (revert) neden olmak. Bu, başarısız harici çağrıları zorlayarak (örneğin, fonları reddeden bir sözleşmeye göndermek), `require` koşullarının başarısız olması için durumu manipüle ederek veya diğer ele alınmayan istisnalar yoluyla tetiklenebilir. Eğer bir sözleşme, başarısız olan (belki de kötü niyetle tetiklenmiş) bir harici çağrıya dayanıyorsa, tüm operasyon engellenebilir.

Akıllı sözleşmelerin değişmez doğası, DoS'u özellikle ciddi hale getirir. Başarılı bir saldırı, kalıcı olarak kilitlenmiş fonlara veya kurtarılamaz işlevselliğe yol açabilir, çünkü sözleşme kodu dağıtımdan sonra (post-deployment) kolayca düzeltilemez.

Etki azaltma, güvenli kodlama uygulamalarına dayanır: sınırsız döngüler yerine sınırlı işlemler kullanmak, kullanıcılara fonları itmek ("push-payment") yerine transfer hatalarını izole eden "pull-payment" (çekme ödemesi) desenlerini tercih etmek, harici çağrı hatalarını sağlam bir şekilde ele almak (örneğin, uygun yerlerde `try/catch` kullanmak) ve dikkatli gas yönetimi.

Link

Overflow

Tamsayı taşması (integer overflow) ve alt taşması (integer underflow) güvenlik açıkları, akıllı sözleşme güvenliği alanında sürekli bir tehdit oluşturur ve sabit boyutlu tamsayı aritmetiğinin temel sınırlamalarından kaynaklanır. Taşma, bir aritmetik işlemin sonucunun kendi türü için maksimum değeri aşması durumunda, alt taşma ise sonucun minimum değerin altına düşmesi durumunda meydana gelir.

Geçmişte, Solidity'nin 0.8.0 öncesi sürümlerinde, bu aritmetik hatalar değerin sessizce "başa dönmesine" (wrap around) neden oluyordu. Örneğin, maksimum uint8 değerine (255) 1 eklemek 0 sonucunu verirken, 0'dan 1 çıkarmak 255 sonucunu veriyordu. Bu öngörülebilir ancak kontrolsüz davranış, saldırganların token bakiyelerini manipüle etmelerine (örneğin, büyük miktarlarda token basmalarına veya bakiyelerin başa dönmesini sağlayarak fonları boşaltmalarına), kritik güvenlik kontrollerini atlamalarına, sözleşme durumunu bozmalarına veya hizmet reddine (denial-of-service) neden olmalarına olanak tanıyan önemli bir exploit kaynağıydı.

Solidity sürüm 0.8.0, önemli bir güvenlik iyileştirmesi getirdi: standart aritmetik işlemler (+, -, *, /) artık varsayılan olarak taşma ve alt taşma kontrolleri gerçekleştirir. Eğer bir işlem başa dönmeye neden olacaksa, işlem bunun yerine geri alınır (revert), böylece durumun sessizce bozulması önlenir.

Ancak risk tamamen ortadan kalkmış değildir. Geliştiriciler, genellikle gaz optimizasyonu için `unchecked` blokları kullanarak bu varsayılan kontrolleri açıkça atlayabilirler. Bir `unchecked` bloğu içindeki kod, 0.8.0 öncesi sürümlerin tehlikeli sessiz başa dönme davranışına geri döner ve son derece dikkatli bir doğrulama gerektirir. Benzer şekilde, düşük seviyeli EVM assembly kodu Solidity'nin kontrollerinden faydalanmaz ve aritmetik işlemler için manuel güvenlik yönetimi gerektirir. Ek olarak, kaydırma işlemleri (<<, >>) varsayılan >=0.8.0 modunda bile kontrolsüz kalır ve sonuçları kırpar. Uygun olmayan tür dönüşümü (type casting) (örneğin, büyük bir uint256'yı uint8 gibi daha küçük bir türe dönüştürmek) de değer kırpılmasına yol açabilir ve sonraki hesaplamalarda potansiyel olarak beklenmedik davranışlara neden olabilir.

Bu nedenle, modern Solidity'de varsayılan olarak önemli ölçüde azaltılmış olsa da, tamsayı taşması/alt taşması, özellikle eski sözleşmelerde (legacy contracts), `unchecked` blokları veya assembly kullanan kodlarda ve belirli kontrol edilmeyen işlemler veya dikkatsiz tür dönüşümleri yoluyla hala geçerli bir güvenlik açığı olmaya devam etmektedir.

Link

tx.origin Authentication

Solidity akıllı sözleşmelerinde yetkilendirme mantığı için `tx.origin` kullanımı, kritik bir güvenlik açığı oluşturur. Bu durum, `msg.sender`'a kıyasla davranışının temelden yanlış anlaşılmasından kaynaklanır. `tx.origin` işlemi başlatan EOA'yı (Externally Owned Account / Harici Sahipli Hesap) tutarlı bir şekilde tanımlarken, `msg.sender` ise doğrudan çağırıcıyı tanımlar. `tx.origin`'in izin kontrolleri için kullanılması, sözleşmeyle doğrudan etkileşim kuran varlığın doğrulanmasında başarısız olur.

Bu zafiyet, oltalama (phishing) tarzı saldırılara kapı aralar; bu saldırılarda, ayrıcalıklı bir kullanıcı tarafından çağrılan kötü niyetli bir aracı sözleşme, hedef sözleşmedeki korunan fonksiyonları başarıyla çağırabilir. `tx.origin` kontrolü yanlış bir şekilde asıl kullanıcıyı doğrular, bu da kötü niyetli sözleşmenin kullanıcının yetkisiyle işlem yapmasına olanak tanır. Sonuçlar, doğrudan Ether ve token hırsızlığından sözleşme durumunun yetkisiz manipülasyonuna kadar uzanır ve potansiyel olarak ciddi mali kayıplara ve protokolün bütünlüğü ile itibarına onarılamaz zararlar vermeye neden olabilir.

Link

Access Control

Yetersiz Erişim Kontrolü, Solidity akıllı sözleşmelerinde kimin hangi fonksiyonları çalıştırabileceğine dair kısıtlamaların eksik veya yanlış uygulandığı kritik bir güvenlik açığıdır. Solidity'de yerleşik izin modelleri bulunmadığından, geliştiricilerin manuel olarak, genellikle onlyOwner gibi değiştiriciler kullanarak veya Rol Tabanlı Erişim Kontrolü (RBAC) uygulayarak kontroller eklemesi gerekir. Bunun doğru şekilde yapılmaması güvenlik açıkları oluşturur.

Bu güvenlik açığı tipik olarak korunmasız fonksiyonlar şeklinde kendini gösterir. Sözleşme sahipliğini devretme (changeOwner), fon çekme (withdraw), sözleşmeyi duraklatma, token basma veya hatta sözleşmeyi yok etme (selfdestruct) gibi yönetimsel veya hassas işlemler için tasarlanmış fonksiyonlar, herhangi bir dış hesap tarafından çağrılabilir durumda bırakılabilir. Bu durum genellikle eksik erişim kontrolü değiştiricileri veya yanlış fonksiyon görünürlüğü (örneğin, belirtilmediği takdirde fonksiyonların varsayılan olarak public olması) nedeniyle meydana gelir. Yalnızca bir kez çalışması gereken, açığa çıkan başlatma fonksiyonları da, dağıtımdan sonra çağrılabilir kalırlarsa bir saldırı vektörü olabilir ve potansiyel olarak saldırganların sahipliği veya kritik parametreleri sıfırlamasına olanak tanır.

Sonuçları, yetkisiz kullanıcıların yönetimsel ayrıcalıklar elde etmesinden, sözleşme tarafından yönetilen fonların tamamen çalınmasına veya sözleşmenin geri döndürülemez şekilde yok edilmesine kadar varan ölçüde ciddidir. Parity Cüzdanı olayları ve LAND Token hacklenmesi gibi gerçek dünya exploit'leri, yetersiz erişim kontrolünün yıkıcı potansiyelini göstermektedir.

Azaltma yöntemleri arasında, tüm hassas fonksiyonlara erişim kontrolü denetimlerini titizlikle uygulamak, En Az Ayrıcalık İlkesi'ne bağlı kalmak, Ownable veya RBAC gibi yerleşik desenleri (genellikle OpenZeppelin gibi kütüphaneler aracılığıyla) kullanmak ve kapsamlı testler ve denetimler yapmak yer alır.

Link

Weak Randomness

Ethereum Sanal Makinesi'nde (EVM) güvenli rastgelelik üretmek, ağ konsensüsü için gerekli olan deterministik doğası nedeniyle zordur. Bu, tamamen zincir üzerindeki verilerden türetilen görünüşte rastgele değerlerin aslında tahmin edilebilir olduğu bir "entropi yanılsaması" yaratır.

Geliştiriciler genellikle block.timestamp, blockhash ve Birleşme sonrası prevrandao (block.difficulty aracılığıyla erişilir) gibi kolayca erişilebilen blok değişkenlerini sözde rastgelelik kaynakları olarak yanlış kullanırlar. Bu değişkenler tahmin edilebildikleri veya etkilenebildikleri için güvensizdir.

Madenciler (Proof-of-Work'te) veya doğrulayıcılar (Proof-of-Stake'te) genellikle MEV (Maksimum Çıkarılabilir Değer) stratejilerinin bir parçası olarak haksız avantaj elde etmek için bu değerleri bir dereceye kadar manipüle edebilirler. Önemli bir şekilde, rastgelelik mantığı yalnızca işlem yürütülmeden önce veya sırasında bilinen girdilere dayanıyorsa, sıradan kullanıcılar veya saldırgan sözleşmeler bile genellikle sonuçları tahmin edebilir, bu da front-running gibi istismarlara olanak tanır. Bu öngörülebilirlik, piyangolar, oyunlar ve NFT mint'leri gibi uygulamaların adaletini baltalar.

Link

Hash Collision

Birden Fazla Dinamik Tür ile `abi.encodePacked` Yoluyla Hash Çakışması, altta yatan Keccak-256 hash fonksiyonunun zayıflıklarından değil, verilerin hash'lenmeden önce kodlanma biçiminden, özellikle Solidity'nin `abi.encodePacked` fonksiyonu kullanıldığında ortaya çıkar. Argümanları 32 bayta tamamlayan (padding) ve dinamik türler için uzunluk önekleri içeren standart `abi.encode`'un aksine, `abi.encodePacked`, argümanları gereken minimum bayt kullanarak birleştirerek, küçük statik türler için dolguyu ve en önemlisi `string`, `bytes` veya dinamik diziler gibi dinamik türler için uzunluk bilgisini atlayarak kompakt, standart dışı bir kodlama oluşturur.

Asıl sorun, `abi.encodePacked`'in iki veya daha fazla bitişik dinamik tür argümanıyla kullanıldığında ortaya çıkar. Her dinamik argümanın uzunluğu kodlanmadığından, sonuçtaki bayt dizisinde aralarındaki sınır belirsiz hale gelir. Bu belirsizlik, genellikle önemsiz bir şekilde, tam olarak aynı paketlenmiş bayt dizisini üreten farklı mantıksal girdi setleri oluşturmayı mümkün kılar. Örneğin, `abi.encodePacked("a", "bc")`, `abi.encodePacked("ab", "c")` ile aynı bayt çıktısını verir.

Bu özdeş bayt çıktısı daha sonra hash'lendiğinde (örneğin, `keccak256(abi.encodePacked(...))`), aynı hash değeriyle sonuçlanır; bu, kodlamadan kaynaklanan bir hash çakışmasıdır.

Bu kodlama çakışması güvenlik açığı, elde edilen hash güvenlikle ilgili hassas bir bağlamda kullanılırsa çeşitli şekillerde istismar edilebilir:

İmza Doğrulamasını Atlama: Bir saldırgan, bir parametre seti için oluşturulmuş geçerli bir imzayı alabilir ve çakışan bir hash üreten farklı, kötü niyetli bir parametre setiyle yeniden kullanabilir. Sözleşmenin imza doğrulaması (`ecrecover`) başarılı olacak ve yetkisiz yürütmeye izin verecektir.

Mapping Anahtar Çakışmaları Yoluyla Durum Bozulması: Çakışmaya açık hash bir mapping'de (`mapping(bytes32 => ...)`) anahtar olarak kullanılırsa, bir saldırgan meşru bir kullanıcının anahtarıyla çakışan bir anahtar oluşturmak için girdiler hazırlayabilir, potansiyel olarak verilerini üzerine yazabilir, erişim kontrollerini atlayabilir veya hizmet reddine neden olabilir.

Mesaj Kimlik Doğrulama Sorunları: Güvenlik açığı, farklı mantıksal mesajlar hash'lendikten sonra aynı görünebileceğinden, veri bütünlüğünü sağlamak için hash'e dayanan kontrolleri baltalar.

Başarılı bir istismarın sonuçları, işlevlere veya verilere Yetkisiz Erişim, doğrudan Fon Hırsızlığı (Fund Theft), kritik Durum Bozulması ve Hizmet Reddi (DoS) dahil olmak üzere ciddi olabilir.

Link

Precision Loss

Hassasiyet kaybı güvenlik açıkları, tam sayı aritmetiğine dayanmaktan ve kayan noktalı sayılar için yerel desteğin bulunmamasından kaynaklanır. Bu tasarım, deterministik yürütmeyi önceliklendirir ancak geliştiricilerin kesirli değerleri manuel olarak yönetmesini gerektirir, bu da hatalara fırsat yaratır.

Temel sorun tam sayı bölme kesilmesidir: Solidity kalanları atar ve bölme sonuçlarını sıfıra doğru yuvarlar. Bu öngörülebilir davranış, genellikle aşağıdaki gibi kalıplar aracılığıyla istismar edilebilir:

Çarpmadan Önce Bölme: (a * c) / b yerine (a / b) * c hesaplamak, ara sonuç olan a / b'yi keserek hassasiyet kaybını artırır.

Sıfıra Aşağı Yuvarlama: Eğer pay A, payda B'den küçükse (ve her ikisi de pozitifse), A / B her zaman 0 sonucunu verir. Bu, küçük ücretler, ödüller veya token dönüşümleri içeren hesaplamalar için risklidir.

Saldırganlar, finansal kazanç sağlamak amacıyla sözleşme mantığını manipüle etmek için bu matematiksel özelliklerden yararlanır. Yaygın stratejiler şunları içerir:

Durum/Fiyat Manipülasyonu: Döviz kurları, havuz rezervleri, kasa (vault) pay fiyatları veya teminat oranları gibi kritik protokol değerlerini bozmak için yuvarlama hatalarını tetiklemek; bu durum daha sonraki işlemlerde istismar edilebilir.

Uç Durumları Hedefleme: Kesilmenin etkisini en üst düzeye çıkarmak için çok küçük girdilere sahip veya büyük dahili değerlerle etkileşime girecek şekilde tasarlanmış işlemleri kullanmak; bu durum genellikle hesaplamaların sıfır sonuç vermesine neden olur.

Başarılı hassasiyet kaybı saldırıları, önemli olumsuz sonuçlara yol açabilir:

Azaltılmış Maliyetler: Saldırganlar daha düşük veya sıfır ücret/maliyet öder.

Şişirilmiş Kazançlar: Saldırganlar gayri meşru olarak daha fazla token, pay veya ödül alır.

Arbitraj Fırsatları: Saldırganların yararlanması için protokol içinde yapay fiyat farklılıkları yaratmak.

Risk Mekanizmalarını Aşma: Hatalı hesaplamalar nedeniyle likidasyonları veya diğer güvenlik kontrollerini atlamak.

Kademeli Fon Tükenmesi: Küçük yuvarlama hatalarını ("1 wei saldırıları") istismar eden tekrarlanan işlemler yoluyla değeri sifonlamak.

Azaltma, çarpmaları bölmelerden önce yapmak, sayısal ölçeklendirme kullanmak (sabit noktalı matematiği simüle etmek), özel matematik kütüphaneleri kullanmak ve uygun yuvarlama mantığını uygulamak gibi dikkatli aritmetik işlemleri içerir. Standart taşma kontrolleri (SafeMath veya Solidity >=0.8 gibi) bölmeden kaynaklanan hassasiyet kaybını önlemez.

Link

msg.value in loop

Bu güvenlik açığı, bir akıllı sözleşmenin bir döngü içinde msg.value değerini hatalı bir şekilde kullanması durumunda ortaya çıkar. Temel sorun, msg.value değerinin bir işlemin tüm yürütme bağlamı boyunca sabit kalmasından kaynaklanır. Eğer bir döngü, bu iterasyonlar boyunca işlenen veya harcanan kümülatif değeri doğru bir şekilde takip etmeden, her iterasyonda bu başlangıçtaki msg.value değerine dayalı kontroller veya eylemler gerçekleştirerek birden çok kez yinelenirse, bu bir istismar (exploit) fırsatı yaratır.

Bir saldırgan, zafiyetli fonksiyonu tetiklemek için belirli bir miktarda Ether göndererek bunu istismar edebilir. Döngü içinde, require(msg.value >= amount_per_item) gibi kontroller tekrar tekrar geçebilir veya durum güncellemeleri hatalı bir şekilde başlangıçtaki tam msg.value değerini birden çok kez kullanabilir. Bu durum, sözleşme mantığının aynı döngünün önceki iterasyonlarında etkin bir şekilde 'harcanan' veya tahsis edilen değeri hesaba katmamasından kaynaklanır.

Bu kusur, bir saldırganın eylemleri tetiklemesine olanak tanır (Ether transferleri veya dahili bakiye kredileri gibi) ve bu eylemlerin toplam değeri, işlemle birlikte gerçekten gönderdikleri Ether miktarını önemli ölçüde aşar.

Link

ecrecover

ecrecover, akıllı sözleşmelerin bir mesaj özetinden (hash) ve bir ECDSA imzasından (v, r, s) imzalayanın adresini kurtarmasına olanak tanıyan temel bir EVM ön derlemesidir (precompile). Bu, meta işlemler veya izin (permit) fonksiyonları için zincir dışı (off-chain) imzalanmış mesajların doğrulanması gibi kritik işlevleri mümkün kılar. Ancak, doğrudan kullanımı, dikkatli bir şekilde ele alınmazsa, önemli ve genellikle hafife alınan güvenlik riskleri sunar.

Sıfır Adres Döndürme Zafiyeti: Kritik bir sorun, `ecrecover`'ın benzersiz hata işleme mekanizmasından kaynaklanır. Geçersiz veya matematiksel olarak imkansız bir imza ile karşılaşıldığında, işlemi geri almaz (revert). Bunun yerine, sessizce başarısız olur ve sıfır adresini (`address(0)`) döndürür. `ecrecover` çağıran ancak eksik bir sıfır adres kontrolünden muzdarip olan sözleşmeler yüksek derecede savunmasızdır. Bir saldırgan kasıtlı olarak geçersiz imza verileri gönderebilir, bu da `ecrecover`'ın `address(0)` döndürmesine neden olur. Bu çıktı açıkça kontrol edilip reddedilmezse, sözleşme yanlış bir şekilde ilerleyebilir ve `address(0)`'ı meşru imzalayan olarak kabul edebilir. Bu, özellikle sıfır adresinin sözleşmenin özel mantığı içinde özel ayrıcalıkları veya anlamlı bir durumu varsa, yetkisiz durum değişiklikleri, yanlış olay (event) yayınları veya izinlerin verilmesi gibi ciddi sonuçlara yol açabilir. Sağlam kod, her zaman `ecrecover` çağrısından hemen sonra `recoveredAddress != address(0)` kontrolünü yapmalıdır.

İmza Esnekliği (Malleability) Zafiyeti: İkinci büyük risk, ECDSA algoritmasının kendisinin doğal bir özelliğinden kaynaklanır: imza esnekliği. Belirli bir mesaj ve özel anahtar için, birden fazla farklı ancak kriptografik olarak geçerli imza temsili mevcut olabilir (özellikle, `s` bileşenini kullanan bir imza, genellikle `n-s` kullanılarak geçerli bir imzaya dönüştürülebilir, burada `n` eğrinin derecesidir). Bu, sözleşmelerin bir mesaj için imzanın benzersiz olduğunu yanlış bir şekilde varsayması durumunda bir zafiyet haline gelir. Saldırganlar, benzersizlik kontrollerini atlayarak bunu istismar edebilirler. Örneğin, bir sözleşme tekrarları (replay) önlemek için imzanın kendisinin özetini (hash) bir nonce olarak kullanıyorsa (kusurlu bir desen), bir saldırgan geçerli bir imza alabilir, esnek karşılığını hesaplayabilir ve eylemi tekrar yürütmek için gönderebilir, çünkü imza özetleri farklı olacaktır. Ayrıca, eğer harici sistemler veya sözleşme mantığının parçaları her iki geçerli imza biçimini de işlemek üzere tasarlanmamışsa, belirli bir imza biçimi bekleyen sistemlerde beklenmedik davranışlara veya tekrarlara neden olabilir. Etkili azaltma, imza kanonikleştirilmesini zorunlu kılmayı içerir – OpenZeppelin'in ECDSA'sı gibi standart kütüphanelerde sağlam bir şekilde uygulanan bir kontrol olup, doğrudan `ecrecover` kullanımına tercih edilmelidir.

Link

Replay

Zincirler Arası Tekrar Saldırısı (CCRA): Bir EVM zincirinde geçerli olarak yürütülen bir işlem yakalanır ve farklı bir EVM zincirinde başarılı bir şekilde yeniden gönderilir. Bu, zincirler arasındaki işlem formatları ve imzalardaki benzerliklerden yararlanır, özellikle işlemlerin benzersiz zincir tanımlayıcılarından (Chain ID) yoksun olduğu durumlarda. Ethereum/Ethereum Classic hard fork'u (sert çatallanması), bu riskin gerçekleştiği klasik bir örnektir. EIP-155, Chain ID'yi standart işlem imzalarına gömerek ve böylece onları zincire özgü hale getirerek bunu azaltmak için tanıtılmıştır. Ancak, özel imza doğrulaması kullanan akıllı sözleşmelerin (smart contract'ların) de Chain ID'yi açıkça kontrol etmesi gerekir. Wintermute'a karşı gerçekleştirilen 20 milyon dolarlık Optimism istismarı (exploit'i), zincirler arası (cross-chain) dağıtılmış bir sözleşmede böyle bir eksik Chain ID kontrolünden kaynaklanmıştır.

Akıllı Sözleşme Seviyesinde Tekrar (Aynı Zincir): İmzalı bir mesaj veya işlem, aynı akıllı sözleşmeye veya potansiyel olarak aynı zincirdeki başka bir sözleşmeye karşı tekrar oynatılır (replayed). Bu genellikle, sözleşmenin kendi mantığındaki güvenlik açıklarından yararlanır, özellikle meta işlemler (meta-transactions) veya ERC-20 izin (permit) fonksiyonları gibi özellikler için kullanılan özel imza doğrulama şemalarında. En yaygın kusur, uygulama düzeyinde bir nonce'ın (tek seferlik numaranın) yokluğu veya yanlış uygulanmasıdır. Bir nonce («bir kez kullanılan numara»), imzalayanla ilişkili benzersiz bir sayaçtır; her bir özel imzanın yalnızca tek bir eyleme izin verdiğinden emin olmak için imzalı mesaj özetine (digest) dahil edilmesi ve sözleşme tarafından zincir üzerinde (on-chain) takip edilmesi gerekir.

Link

Inheritance Order

Solidity'nin çoklu kalıtım desteği, bir sözleşmenin aynı anda birkaç üst sözleşmeden özellikler devralmasına olanak tanır. Kodun yeniden kullanımı için güçlü olsa da, bu durum "Elmas Problemi" olarak bilinen potansiyel bir belirsizliğe yol açar: iki veya daha fazla temel sözleşme aynı ada ve parametrelere sahip bir işlevi tanımlarsa.

Bunu çözmek için Solidity, her sözleşme için tek ve deterministik bir Metot Çözümleme Sırası (Method Resolution Order, MRO) oluşturmak üzere C3 doğrusallaştırma algoritmasını kullanır. Bu MRO, işlev çağrılarını çözerken temel sözleşmelerin hangi kesin sırayla kontrol edileceğini belirler.

Güvenlik açığı doğrudan bu MRO'nun nasıl belirlendiğinden kaynaklanır. Kritik faktör, geliştiricinin temel sözleşmeleri `is` ifadesinde hangi sırayla listelediğidir. Solidity, sözleşmelerin "en temel benzerinden" "en türetilmişe" doğru listelenmesini gerektirir. Bu belirtilen sıra, C3 algoritması tarafından üretilen nihai MRO'yu doğrudan etkiler.

Güvenlik açığı, geliştiricinin amaçlanan mantıksal hiyerarşiye veya önceliğe uymayan bir kalıtım sırası sağlaması durumunda ortaya çıkar. Daha genel bir sözleşme daha spesifik bir sözleşmeden sonra listelenirse veya sıra başka bir şekilde MRO'nun amaçlanmayan bir işlev uygulamasını önceliklendirmesine neden olursa, sözleşme beklenmedik şekilde davranabilir. Örneğin, bir çağrı, amaçlanan ancak yanlış sıralanmış türetilmiş bir sözleşme geçersiz kılmasında uygulanan kritik güvenlik kontrollerinden veya güncellenmiş mantıktan yoksun bir temel işleve çözümlenebilir.

Yanlış kalıtım sırası nedeniyle yanlış işlevin yürütülmesinin sonuçları arasında erişim kontrollerini atlama, güncel olmayan veya yanlış iş mantığını yürütme, durum bozulması ve potansiyel mali kayıp yer alır. Esasen, sözleşmenin gerçek yürütme akışı geliştiricinin tasarımından saparak güvenliği ve işlevselliği zayıflatır.

Link

MEV

Maksimum Çıkarılabilir Değer (Maximal Extractable Value - MEV), blok üreticilerinin ve özel arayıcıların (searchers), standart blok ödülleri ve gas ücretlerinin ötesinde, bir blok içindeki işlemlerin dahil edilmesini ve sıralamasını manipüle ederek elde edebilecekleri kârı temsil eder. Başlangıçta "Madenci Çıkarılabilir Değeri" (Miner Extractable Value) olarak adlandırılan bu kavram, ödüle olan açgözlülüğünü yansıtmak için "Maksimum" olarak değiştirilmiştir.

MEV, bekleyen işlemlerin genellikle mempool adı verilen ve herkes tarafından görülebilen halka açık bir bekleme alanında bulunması nedeniyle ortaya çıkar. Blok üreticileri, bir bloktaki işlemlerin nihai sırasına karar verme yetkisine sahiptir. "Arayıcılar" (searchers) tarafından çalıştırılan otomatik botlar, sürekli olarak mempool'u izler, potansiyel sonuçları simüle eder ve genellikle tercihli yerleşimi sağlamak için gas tekliflerini (Öncelikli Gas Müzayedeleri - PGA) kullanarak işlemleri stratejik olarak sıralayarak kârlı fırsatları değerlendirir.

Genellikle saldırı olarak görülen yaygın MEV stratejileri şunlardır:

Önden Koşma (Front-Running): Beklenen fiyat etkisinden kâr elde etmek için bir saldırganın işlemini bir kurbanın işleminden (örneğin, büyük bir DEX işlemi) önce yerleştirmek.

Sandviç Saldırıları (Sandwich Attacks): Manipülasyonun neden olduğu fiyat farkını (kayma/slippage) yakalamak için bir kurbanın DEX işlemini hem önden koşma hem de arkadan koşma (back-running) ile çevrelemek.

Tam Zamanında Likidite (JIT Liquidity): Ücretleri yakalamak için yoğunlaştırılmış likidite DEX'lerinde büyük bir takas (swap) etrafına geçici olarak likidite eklemek ve kaldırmak.

Oracle Manipülasyonu (Oracle Manipulation): Kâr amacıyla, genellikle borç verme protokollerini etkileyen fiyat oracle (fiyat kahini) güncellemelerini veya yanlışlıklarını kötüye kullanmak.

Diğer türler arasında NFT keskin nişancılığı (NFT sniping) ve toz saldırıları (dust attacks) bulunur.

Kullanıcılar için sonuçları arasında gaz savaşları (gas wars) nedeniyle artan işlem maliyetleri, işlemlerde daha kötü gerçekleşme fiyatları (kayma/slippage), likidite sağlayıcıları için artan geçici kayıp (impermanent loss) ve haksız yere tetiklenen tasfiyeler (likidasyonlar) yer alır.

Azaltma stratejileri, MEV'in olumsuz etkisini azaltmayı amaçlar. İşlemleri özel mempool'lar veya röleler (Flashbots Protect veya MEV Engelleyici gibi) aracılığıyla göndermek, onları kamuya açık görünümden gizler. Commit-Reveal (Taahhüt-Açıklama) şemaları gibi uygulama seviyesi tasarımlar, sıralama sabitlenene kadar işlem ayrıntılarını gizlerken, oracle'lar için Zaman Ağırlıklı Ortalama Fiyatlar (TWAP) kullanmak manipülasyon risklerini azaltabilir.

Akıllı Sözleşme Güvenlik Danışmanlığı

Geliştirme başlamadan önce uzman blok zinciri danışmanlığı alın. Güvenli, verimli akıllı sözleşmeler ve protokoller tasarlamanıza, maliyetli hatalardan kaçınmanıza ve performansı optimize etmenize yardımcı oluyoruz. Şirket içinde işe alımdan daha hızlı ve daha uygun fiyatlı. Bugün ücretsiz bir danışmanlık randevusu alın!