Zabránění přetečení vyrovnávací paměti

Přetečení vyrovnávací paměti je jedním z nejběžnějších zdrojů bezpečnostních rizik. Přetečení vyrovnávací paměti je v podstatě způsobeno tím, že je s nekontrolovaným, externím vstupem nakládáno jako s důvěryhodnými daty. Kopírování těchto dat pomocí operací, jako je copyMemory, strcat, strcpynebo wcscpy, může vytvářet neočekávané výsledky, což umožňuje poškození systému. V nejlepším případě se vaše aplikace ukončí s výpisem paměti, chybou segmentace nebo porušením přístupu. V nejhorších případech může útočník zneužít přetečení vyrovnávací paměti zavedením a spuštěním dalšího škodlivého kódu ve vašem procesu. Kopírování nezkontrolovaných vstupních dat do vyrovnávací paměti založené na zásobníku je nejčastější příčinou zneužitelných chyb.

Warning

Nikdy nepoužívejte nevázané řetězcové funkce (strcpy, strcat, sprintf, gets) v kódu citlivém na zabezpečení. Nahraďte je jejich ohraničenými ekvivalenty (StringCbCopy, StringCbCat, StringCbPrintf) z bezpečné knihovny řetězců nebo použijte varianty příponY C11 _s (strcpy_s, strcat_s).

Přetečení vyrovnávací paměti může probíhat různým způsobem. Následující seznam obsahuje stručný úvod k několika typům přetečení vyrovnávací paměti a nabízí několik nápadů a zdrojů, které vám pomůžou vyhnout se vytváření nových rizik a zmírnění stávajících situací:

přetečení statické vyrovnávací paměti

K přetečení statického bufferu dochází, když je buffer, který byl deklarován na zásobníku, naplněn více daty, než kolik mu bylo přiděleno. Méně zjevné verze této chyby se vyskytují, když se neověřené vstupní data uživatele zkopírují přímo do statické proměnné, což způsobuje potenciální poškození zásobníku.

přetečení haldy

Přetečení haldy, například přetečení statické vyrovnávací paměti, může vést k poškození paměti a zásobníku. Vzhledem k tomu, že přetečení dochází v paměti haldy místo na zásobníku, někteří lidé je považují za méně závažné při způsobování vážných problémů; přetečení haldy však vyžadují skutečnou programátorskou opatrnost a jsou stejně schopná představovat systémová rizika jako přetečení statické vyrovnávací paměti.

chyby indexování pole

Chyby indexování polí jsou také zdrojem přetečení paměti. Pečlivá kontrola hranic a správa indexů pomůže zabránit tomuto typu přetečení paměti.

Zabránění přetečení vyrovnávací paměti je primárně o psaní dobrého kódu. Vždy ověřte všechny své vstupy a selhávejte s elegancí, pokud je to nutné. Další informace o psaní zabezpečeného kódu najdete v následujících zdrojích informací:

  • Maguire, Steve [1993], psaní solid code, ISBN 1-55615-551-4, Microsoft Press, Redmond, Washington.
  • Howard, Michael a LeBlanc, David [2003], Psaní zabezpečeného kódu, 2. vydání, ISBN 0-7356-1722-8, Microsoft Press, Redmond, Washington.

Poznámka

Tyto prostředky nemusí být dostupné v některých jazycích a zemích.

 

Bezpečná manipulace s řetězci je dlouhodobý problém, který se stále řeší jak pomocí osvědčených programovacích postupů, tak často pomocí zabezpečených funkcí pro manipulaci s řetězci. Příkladem takové sady funkcí pro prostředí Windows začíná StringCbCat.

Zmírnění rizik kompilátoru a linkeru

Moderní verze kompilátoru Microsoft C/C++ a linkeru poskytují několik vrstev ochrany proti přetečení vyrovnávací paměti. Vždy povolte tyto ochrany v produkčních buildech:

Flag Purpose
/GS Detekce přetečení vyrovnávací paměti zásobníku (ve výchozím nastavení povolena). Před vrácením adres vloží soubory cookie zabezpečení.
/sdl Umožňuje další bezpečnostní kontroly, včetně přísnějšího chování /GS a inicializace proměnných.
/DYNAMICBASE Randomizace rozložení adresního prostoru (ASLR) Náhodně mění adresy načítání, aby se ztížilo zneužití.
/NXCOMPAT Prevence spuštění dat (DEP). Označí stránky paměti jako nespustitelné.
/CETCOMPAT Technologie Intel CET (Control-flow Enforcement Technology) pro hardwarově vynucený stínový zásobník.
/guard:cf Ochrana toku řízení (CFG) Ověřuje cíle nepřímých volání za běhu.

Important

Pro veškerý nový kód kompilujte minimálně s /sdl a /GS. U bezpečnostně kritických aplikací také povolte /guard:cf a linkujte s /CETCOMPAT, pokud cílíte na hardware, který podporuje CET.

Nástroje pro analýzu modulu runtime

Tyto nástroje můžete použít během vývoje a testování k detekci problémů s bezpečností paměti před dosažením produkčního prostředí:

  • AddressSanitizer (ASan): Zkompilujte s /fsanitize=address, abyste za běhu odhalili přetečení vyrovnávací paměti, použití po uvolnění a další chyby v paměti. K dispozici v Visual Studio 2019 16.9 a novějších verzích.
  • Verifikátor aplikace: Detekuje poškození haldy, nesprávné použití deskriptorů a další běžné programátorské chyby.
  • Statická analýza (/analyze): Integrovaný statický analyzátor detekuje přetečení vyrovnávací paměti, neinicializované proměnné a další problémy v době kompilace.