Arabellek taşmaları büyüktür. C'deki hiçbir şey varsayılan olarak aralık kontrolünden geçirilmez, bu nedenle bir tamponun üzerine yazmak çok kolaydır. gets()
Arabellek taşmasını engelleyemeyen ve neredeyse hiç kullanılmaması gereken standart bir kütüphane işlevi vardır .
Yığın bloklarını karıştırmak gibi sömürüyü engellemek için uygulama düzeyinde bazı teknikler vardır, ancak bu, yerel bir arabellekteki arabellek taşmalarını durdurmaz, bu da genellikle bir işlevin geri döneceği adresi değiştirmek gibi ilginç şeyler yapabilir.
C'de iyi bir genel çözüm yoktur. Birçok kütüphane fonksiyonunun yazacakları miktarı sınırlandıracak versiyonları vardır. hesaplama olsa da bu beceriksiz olabilir. Uygun test çalıştırıldığı sürece testte yığın arabellek taşmalarını algılayabilen bir yazılım vardır ve yığın taşması genellikle testte bir kilitlenme olarak görünecektir. Bunun dışında, dikkatli kodlama ve kod incelemesi meselesi.
İlgili bir sorun, bir karakter tarafından çok küçük bir ara belleğe yazma sorunu olup, n karakter uzunluğunda bir C dizesinin, '\0'
sonlandırıcı nedeniyle bellekte n + 1 karakter gerektirdiğini unutmasıdır . Saldırgan bir dizgiyi sonlandırıcı olmadan depolamayı başarabiliyorsa, dize bekleyen herhangi bir C işlevi sıfır baytına ulaşana kadar işlemeye devam eder ve bu da istenenden daha fazla bilgi kopyalanmasına veya çıkmasına neden olabilir (veya bir DOS saldırısı için korumalı belleğe çarpabilir) ). Çözüm yine farkındalık, bakım ve kod incelemeleridir.
Ailenin başka bir riski daha var printf()
. Hiç yazdıysanız char * str; ... printf(str);
, str
yazdırıldığında '%' içeriyorsa, kendinizi sorunlara hazırlıyorsunuz. %n
Biçim yönergesi verir printf()
belleğe yazmak için. Çözüm printf("%s", str);
veya puts(str);
. (Ayrıca, snprintf()
yerine C99 kullanın sprintf()
.)
İmzasız tamsayıların, özellikle döngü dizinleri olarak kullanılması sorunlara neden olabilir. İmzasız olana küçük bir negatif değer atarsanız, büyük bir pozitif değer elde edersiniz. Bu, yalnızca bir şeyin N örneğini işlemek veya gibi sınırlı işlevlerde işlemlere zarar verebilir strncpy()
. Tüm imzalanmamış tam sayıları inceleyin. Bundan kaçınmak isteyebilirsiniz unsigned short
, çünkü bunlardan birindeki büyük bir değer bir int
.
Unutmayın, C cinsinden bir karakter sabiti aslında bir int
. Gibi bir şey yazmak char c; while((c = getchar()) != EOF) ...
kolayca başarısız olabilir, çünkü EOF
a char
.
Düşünebileceğim çok daha karakteristik C hataları var, ancak bunlar güvenlik sorunlarına neden olabilir.