Przepełnienia bufora są duże. Domyślnie nic w C nie jest sprawdzane, więc bardzo łatwo jest nadpisać bufor. Istnieje standardowa funkcja biblioteki gets()
, której nie można zatrzymać przed przepełnieniem bufora i prawie nigdy nie powinna być używana.
Istnieją pewne techniki na poziomie implementacji, które utrudniają wykorzystanie, takie jak szyfrowanie bloków sterty, ale to nie powstrzyma przepełnienia bufora w lokalnych buforach, które często mogą robić interesujące rzeczy, takie jak zmiana adresu, do którego funkcja wróci.
Nie ma dobrego ogólnego rozwiązania w C. Wiele funkcji bibliotecznych ma wersje, które ograniczą ilość, którą będą pisać. chociaż obliczanie tego może być niezdarne. Istnieje oprogramowanie, które może wykryć przepełnienie bufora sterty w teście, o ile przeprowadzany jest odpowiedni test, a przepełnienie stosu często pojawia się jako awaria podczas testowania. Poza tym jest to kwestia starannego kodowania i przeglądu kodu.
Pokrewnym problemem jest problem zapisywania do bufora zbyt małego o jeden znak, zapominając, że ze względu na '\0'
terminator łańcuch C o długości n znaków wymaga n + 1 znaków w pamięci . Jeśli atakującemu uda się zapisać ciąg bez terminatora, dowolna funkcja C oczekująca, że łańcuch będzie kontynuował przetwarzanie, aż osiągnie zero bajtów, co może spowodować skopiowanie lub wysłanie większej ilości informacji niż jest to pożądane (lub uderzenie w chronioną pamięć dla ataku DOS ). Rozwiązaniem są ponownie: świadomość, opieka i recenzje kodu.
Z printf()
rodziną jest jeszcze inne ryzyko . Jeśli kiedykolwiek piszesz char * str; ... printf(str);
, ustawiasz się na problemy, jeśli str
zawiera „%” po wydrukowaniu. %n
Dyrektywa format pozwala printf()
na zapis do pamięci. Rozwiązaniem jest printf("%s", str);
lub puts(str);
. ( snprintf()
Zamiast tego użyj C99 zamiast sprintf()
.)
Używanie liczb całkowitych bez znaku, szczególnie jako indeksów pętli, może powodować problemy. Jeśli przypiszesz małą wartość ujemną do niepodpisanego, otrzymasz dużą wartość dodatnią. Może to podważyć rzeczy takie jak przetwarzanie tylko N wystąpień czegoś lub ograniczone funkcje, takie jak strncpy()
. Sprawdź wszystkie liczby całkowite bez znaku. Możesz tego uniknąć unsigned short
, ponieważ duża wartość jednej z nich zamieni się w dużą wartość dodatnią w int
.
Nie zapominaj, że stała postaci w C jest w rzeczywistości an int
. Pisanie czegoś podobnego char c; while((c = getchar()) != EOF) ...
może łatwo zakończyć się niepowodzeniem, ponieważ EOF
nie będzie reprezentowalne w char
.
Są o wiele bardziej charakterystyczne błędy C, o których mogę myśleć, ale mogą powodować problemy z bezpieczeństwem.