Bezpieczne kodowanie - Secure coding

Bezpieczne kodowanie to praktyka tworzenia oprogramowania komputerowego w sposób chroniący przed przypadkowym wprowadzeniem luk w zabezpieczeniach . Defekty, błędy i błędy logiczne są niezmiennie główną przyczyną powszechnie wykorzystywanych luk w oprogramowaniu. Dzięki analizie tysięcy zgłoszonych luk w zabezpieczeniach specjaliści ds. bezpieczeństwa odkryli, że większość luk wynika ze stosunkowo niewielkiej liczby typowych błędów programistycznych. Identyfikując niebezpieczne praktyki kodowania, które prowadzą do tych błędów, i edukując programistów w zakresie bezpiecznych alternatyw, organizacje mogą podjąć proaktywne kroki, aby znacznie zmniejszyć lub wyeliminować luki w oprogramowaniu przed wdrożeniem.

Zapobieganie przepełnieniu bufora

Przepełnienie bufora , powszechna luka w zabezpieczeniach oprogramowania, ma miejsce, gdy proces próbuje przechowywać dane poza buforem o stałej długości. Na przykład, jeśli jest 8 miejsc do przechowywania przedmiotów, problem wystąpi przy próbie przechowania 9 przedmiotów. W pamięci komputera przepełnione dane mogą nadpisać dane w następnej lokalizacji, co może skutkować luką w zabezpieczeniach (rozbicie stosu) lub zakończeniem programu (błąd segmentacji).

Przykładem programu w C podatnego na przepełnienie bufora jest

int vulnerable_function(char * large_user_input) {
    char dst[SMALL];
    strcpy(dst, large_user_input);
}

Jeśli dane wejściowe użytkownika są większe niż bufor docelowy, nastąpi przepełnienie buforu. Aby naprawić ten niebezpieczny program, użyj strncpy, aby zapobiec możliwemu przepełnieniu bufora.

int secure_function(char * user_input) {
    char dst[BUF_SIZE];
    // copy a maximum of BUF_SIZE bytes
    strncpy(dst, user_input, BUF_SIZE);
}

Inną bezpieczną alternatywą jest dynamiczne przydzielanie pamięci na stercie za pomocą malloc .

char * secure_copy(char * src) {
    size_t len = strlen(src);
    char * dst = (char *) malloc(len + 1);
    if (dst != NULL) {
        strncpy(dst, src, len);
        // append null terminator 
        dst[len] = '\0';
    }
    return dst;
}

W powyższym fragmencie kodu program próbuje skopiować zawartość src do dst, jednocześnie sprawdzając wartość zwracaną przez malloc, aby upewnić się, że można było przydzielić wystarczającą ilość pamięci dla bufora docelowego.

Zapobieganie atakom ciągów formatowych

Format String atak jest, gdy złośliwy użytkownik dostarcza konkretnych wejść, które zostaną ostatecznie wprowadzone jako argument do funkcji, która wykonuje formatowania, takie jak printf () . Atak polega na tym, że przeciwnik czyta ze stosu lub zapisuje do niego .

Funkcja C printf zapisuje dane wyjściowe na standardowe wyjście. Jeśli parametr funkcji printf nie jest poprawnie sformatowany, można wprowadzić kilka błędów bezpieczeństwa. Poniżej znajduje się program, który jest podatny na atak ciągiem formatu.

int vulnerable_print(char * malicious_input) {
	printf(malicious_input);
}

Złośliwy argument przekazany do programu może mieć postać „%s%s%s%s%s%s%s”, który może spowodować awarię programu w wyniku nieprawidłowego odczytu pamięci.

Zapobieganie przepełnieniu liczb całkowitych

Przepełnienie liczby całkowitej występuje, gdy w wyniku operacji arytmetycznej liczba całkowita jest zbyt duża, aby można ją było przedstawić w dostępnym miejscu. Program, który nie sprawdza poprawnie przepełnienia liczby całkowitej, wprowadza potencjalne błędy i exploity w oprogramowaniu.

Poniżej znajduje się funkcja w C++, która próbuje potwierdzić, że suma x i y jest mniejsza lub równa określonej wartości MAX:

bool sumIsValid_flawed(unsigned int x, unsigned int y) {
	unsigned int sum = x + y;
	return sum <= MAX;
}

Problem z kodem polega na tym, że nie sprawdza przepełnienia liczby całkowitej podczas operacji dodawania. Jeśli suma x i y jest większa niż maksymalna możliwa wartość an unsigned int, operacja dodawania przepełni się i być może da wartość mniejszą lub równą MAX, nawet jeśli suma x i y jest większa niż MAX.

Poniżej znajduje się funkcja, która sprawdza przepełnienie, potwierdzając, że suma jest większa lub równa zarówno x, jak i y. Gdyby suma się przepełniła, suma byłaby mniejsza niż x lub mniejsza niż y.

bool sumIsValid_secure(unsigned int x, unsigned int y) {
	unsigned int sum = x + y;
	return sum >= x && sum >= y && sum <= MAX;
}

Zapobieganie przechodzeniu ścieżki

Path traversal to usterka, dzięki której ścieżki dostarczone z niezaufanego źródła są interpretowane w taki sposób, że możliwy jest nieautoryzowany dostęp do plików.

Rozważmy na przykład skrypt, który pobiera artykuł, pobierając nazwę pliku, który jest następnie odczytywany przez skrypt i analizowany . Taki skrypt może używać następującego hipotetycznego adresu URL do pobierania artykułu o karmach dla psów :

https://www.example.net/cgi-bin/article.sh?name=dogfood.html

Jeśli skrypt nie ma sprawdzania danych wejściowych, zamiast tego ufając, że nazwa pliku jest zawsze poprawna, złośliwy użytkownik może sfałszować adres URL, aby pobrać pliki konfiguracyjne z serwera WWW:

https://www.example.net/cgi-bin/article.sh?name=../../../../../etc/passwd

W zależności od skryptu może to ujawnić plik /etc/passwd , który w systemach uniksopodobnych zawiera (między innymi) identyfikatory użytkowników , ich nazwy logowania , ścieżki do katalogów domowych i powłoki . (Zobacz wstrzyknięcie SQL, aby zapoznać się z podobnym atakiem).

Zobacz też

Uwagi

Bibliografia

  • Taylor, Sztuka; Briana Buege'a; Randy Layman (2006). Hakowanie ujawnione J2EE i Java . McGraw-Hill Primis. P. 426. ISBN 0-390-59975-1.

Zewnętrzne linki