Secure by design
Secure by design (bezpečný díky návrhu) je v informatice označení software, který byl navržen od základu tak, aby byl bezpečný. Znamená to, že návrhový vzor je volen tak, aby jeho znalost (tj. znalost principů práce počítačového programu) neohrozila bezpečnost. Riziko, že bude programátorská chyba v programu objevena a crackerem pomocí exploitu bude zneužita, je dnes vysoké. Všechny počítačové programy, které zpracovávají nedůvěryhodné vstupy, které nejsou pod kontrolou uživatele (například webový prohlížeč), by měly dbát základních pravidel bezpečného návrhu.
Charakteristika
Obecně platí, že návrhy, které mají dobře fungovat, by neměly spoléhat na security through obscurity (bezpečnost skrze utajení). Software by měl být navržen tak, že i v případě znalosti návrhu (tj. principů funkce programu) nedojde k omezení bezpečnosti práce programu. Když více lidí vidí zdrojový kód, zvyšuje se šance, že jakékoliv nedostatky budou nalezeny dříve (Linusův zákon). Přitom je ale zdrojový kód s chybou zároveň přístupný útočníkům, kteří mohou chybu také snadněji nalézt.
Také je velmi důležité, aby vše fungovalo s minimálním množstvím oprávnění (princip nejnižších privilegií). Například webový server, který běží jako uživatel s oprávněními správce počítače (tj. root v unixových systémech, administrator ve Windows NT), může obsahovat chybu, která umožní běžnému uživateli změnu v systému, kterou by jinak mohl dělat jen správce počítače. Chyba v programu tak může ohrozit celý počítačový systém. Proto je používán princip nejnižších privilegií, kdy ani v případě chyby v programu nedojde k ohrožení celého systému (např. sandbox).
Chyba v programu může umožnit obejití autentizačního systému, takže s počítačem může pak manipulovat i útočník, který na něm nemá uživatelský účet.
Návrh bezpečného software
Hlavním předpokladem kvalitního návrhu software je kontrola vstupů do programu. Následující program v jazyce C demonstruje systematickou chybu návrhu při zpracování vstupu:
#include <stdio.h>
int main()
{
char buffer[100];
printf("Jak se jmenujete?\n");
gets(buffer);
printf("Ahoj, ");
printf(buffer);
printf("!\n");
return 0;
}
Funkce gets ve standardní knihovně jazyka C zapisuje do bufferu, dokud nenalezne znak nového řádku (CR) nebo EOF. Zadání více než 99 znaků na vstupu výše uvedeného programu znamená přetečení vyrovnávací paměti na zásobníku. Rezervace 100 znaků pro vyrovnávací paměť s předpokladem, že téměř každé křestní jméno od uživatele není delší, než 99 znaků, nebrání uživateli skutečně napsat více než 99 znaků. To může vést ke spuštění libovolného strojového kódu.
Druhá vada je, že se program tiskne výstup přímo funkcí printf, která interpretuje v obsahu prvního argumentu speciální zástupné formátovací znaky (např. %s
, %d
atd.) a tiskne pomocí nich dalšími argumenty ze svého zásobníku. Jestliže útočník zadá uvnitř vstupu znaky %d
, program se pokusí vytisknout neexistující celočíselnou hodnotu ze zásobníku a může dojít k nepředvídatelnému chování (podle toho, co se zrovna nachází na vrcholu zásobníku).
Podobný problém může nastat, pokud ve webovém skriptu nejsou ověřeny vstupní parametry. Například skript, který načte článek tím, že je jako parametr zadán název souboru, který je pak přímo načten a parsován. V následujícím hypotetickém URL je načten soubor clanek.html
:
http://www.example.net/cgi-bin/article.sh?name=clanek.html
Pokud skript neprovádí žádné vstupní kontroly, tak věří, že název souboru je platný, a proto může cracker pomocí URL získat konfigurační soubory z webového serveru:
http://www.example.net/cgi-bin/article.sh?name=../../../../../etc/passwd
Pokud je cílovým systémem unixový webový server, může útočník získat soubor /etc/passwd
, který obsahuje seznam uživatelských jmen, jejich identifikátory (UID), cesty k domácím adresářům a podobně. Podobně může probíhat SQL injection útok.