|
Ez a szócikk vagy szakasz lektorálásra, tartalmi javításokra szorul. |
A tervezett biztonság (ang.: secure by design) a programtervezésben azt jelenti, hogy a program megtervezése az alapoktól kezdve biztonságos legyen. Az ilyen megközelítésben előbb mérlegelik a különféle biztonsági taktikákat, majd ezek közül a legjobbakat választják ki és alkalmazzák az architektúra kialakításával, s ezeket vezérelvként veszik alapul a fejlesztők számára.[1]
A tervezett biztonság egyre jobban a fő fejlesztéssé válik, megközelítve, biztosítva a biztonságot és titkosítást a programozás rendszerében. Ebben a megközelítésben a biztonság felépítése a rendszerben az alapoktól indul, és egy erős építészeti tervezéssel kezdődik. A biztonsági építészeti tervezési döntések gyakran alapulnak a jól ismert biztonsági taktikák és minták meghatározott, újrafelhasználható technikákként a speciális minőségi vonatkozások elérésére. A biztonsági taktikák/minták megoldásokat kínálnak végrehajtásra a szükséges hitelesítési, meghatalmazási, titoktartási, az adatok integritása, titoktartás, felelősségre vonhatóság, elérhetőség, biztonság és megtagadási követelmények, akkor is ha a rendszer támadás alatt van.[2] Hogy biztosítsuk a biztonságot a szoftver rendszerben, nemcsak az a legfontosabb, hogy erős biztonsági felépítést tervezzünk (szándékosan), de az is különösen fontos, hogy megőrizzük (végrehajtott) a felépítést a szoftver fejlődése alatt. A rosszindulatú szokások adottak, és vigyázni kell, hogy minimalizáljuk a hatásait, várhatóan a biztonsági réseknél, amikor felfedezik azokat, vagy érvénytelen felhasználói bevitel esetén.[3] Szorosan kapcsolódik ezekhez a gyakorlatban a „jó” szoftvertervezés használata, mint a domainvezérelt tervezés, a natív felhőalapú technológia, a biztonság növekedésének eszközeként, csökkentve annak a kockázatát, ha hiba történne a biztonsági rés megnyitásával, még ha a tervezési alapelvek eredetileg nem is biztonsági célokra készültek.
Általában a jól működő tervezések nem támaszkodnak titkosításra. Gyakran a titoktartás csökkenti a támadók számát, demotiválva a fenyegető populáció részhalmazát. A logika az, hogy ha növekedés van a komplexitásban a támadónál, akkor a megnövekedett támadói erőfeszítés veszélyezteti a célt. Míg ez a technika az jelenti, hogy csökkentek a velejáró kockázatok, gyakorlatilag végtelen a készlet a fenyegetés szereplőinek és technikáinak alkalmazásában, ez okozza idővel a legtöbb titkosítási módszer bukását. Míg nem kötelező, a megfelelő biztonság azt jelenti, hogy mindenkinek lehetővé teszik a tervezés megismerését és a megértését, mert ez a megfelelő biztonság. Ennek megvan az az előnye, hogy ha több ember néz rá a számítógépes kódokra, az javítja az esélyét annak, hogy a hibák hamarabb kiderüljenek (lásd: Linus törvénye). A támadók szintén hozzáférnek a kódokhoz, ami könnyebbé teheti a rések megtalálását.
Továbbá fontos, hogy minden lehetőleg jogosultság alapján működjön (lásd: legkisebb jogosultság elve). Például egy webszerver, ami adminisztrátori felhasználóként („gyökér” vagy admin) fut, kiváltságokat jelent a felhasználónak, fájlokat és felhasználókat törölhet, melyek nem tartoznak sehova. Egy hiba a programban az egész rendszert veszélybe sodorhatja, viszont ha a webszerver egy izolált rendszerben fut, és csak a szükséges hálózati és a fájlrendszeri hozzáféréssel rendelkezik, akkor nem veszélyeztetheti a futtatást, kivéve ha a rendszer hibás.
Sok dolog, különösen a bemenetek, gyanakvóvá kell tegye a biztonságos kialakítást. Egy hibatűrő program is bizalmatlanságot eredményezhet a belső tagok között.
Két példa a nem biztonságos tervezésre: a puffertúlcsordulás és a format string rések. A következő C nyelven írt program szemlélteti ezeket a hibákat.
#include <stdio.h>
int main()
{
char a_chBuffer[100];
printf("Hogy hívnak?\n");
gets(a_chBuffer);
printf("Üdvözöllek, ");
printf(a_chBuffer);
printf("!\n");
return 0;
}
Mivel a get funkciót a szabványos C könyvtár tartalmazza, ezért nem állítja le a byte-ok írását a buffer
-be, amíg nem olvas egy új sort vagy a fájl végét, begépelve több mint 99 karaktert azonnali puffer túlcsordulást okoz. Kiosztani 100 karaktert a buffer
-nek a feltevés szerint, hogy minden a felhasználó által adott név nem lesz hosszabb 99 karakternél, nem akadályozza meg a felhasználót, hogy több mint 99 karaktert gépeljen be. Ez vezethet tetszőleges gépi kód végrehajtásához.
A második hiba, hogy a program megpróbálja kiíratni a bemenetet, közvetlenül átadva a printf
funkciónak. Ez a funkció kiíratja az első argumentumot, lecserélve a konverzió specifikációkat (mint a "%s
", "%d
", stb.) egymás után más argumentumok helyettesítésével a hívási listából. Így, ha a rosszindulatú felhasználó „%d
” parancsot ír be a saját neve helyett, a program megkísérli kinyomtatni a nemlétező egész értéket, és előfordulhat meghatározatlan viselkedés (ang.: undefined behaviour).
Hasonló hiba a webprogramozásban, ha egy online szkript nem validálja a megadott paramétereket. Például, képzeljünk el egy a szkriptet, ami lekér egy cikket egy fájlnév alapján, ami olvasásra és elemzésre került a szkript alapján. Egy ilyen szkript valószínűleg a következő hipotetikus URL-t használna, hogy visszakapjon egy cikket a kutyaeledelről.
http://www.example.net/cgi-bin/article.sh?name=kutyaeledel.html
Ha szkriptnek nincs bemeneti (input) ellenőrzése, helyette megbízik abban, hogy a fájlnév mindig érvényes, a rosszindulatú felhasználó az URL-ből nyerhet vissza konfigurációs fájlokat a webserverről:
http://www.example.net/cgi-bin/article.sh?name=../../../../../etc/passwd
A szkripttől függően, kiadhatja az /etc/passwd fájlt, amely a Unix-alapú rendszerekben a felhasználó-azonosítókat (többek között), a belépési nevüket, a kezdő könyvtárak elérését és rendszerhéjakat tartalmazza. (Lásd SQL injektálás a hasonló támadáshoz.)
A szerver/kliens architektúrákban, a program a másik oldalon lehet, hogy nem azonosított kliens, és a kliens szervere nem azonosított szerver. Még ha azok is, egy közbeékelődéses támadás kompromittálhatja a kommunikációt.
Gyakran a legkönnyebb út, hogy feltörjük a kliens/szerver rendszerét, hogy nem egyenesen a biztonsági mechanizmusokat támadjuk, hanem az azt körülvevő rendszert. A közbeékelődéses támadás egy egyszerű példa erre, mert a felhasználó személyes adatai gyűjthetők össze. Ezért is fontos megfontolni a titkosítást, kivonatolást (hash-elést) és más biztonsági mechanizmusokat a tervezésben, biztosítva, hogy a begyűjtött információhoz a potenciális támadók ne férjenek hozzá.
A másik legfontosabb jellemző, hogy a kliens-szervert jó kódolási gyakorlatokkal tervezik. Például követve egy ismert szoftver tervezési struktúrát, így a kliens és a szolgáltató segíthet megtervezni egy jól megépített struktúrát egy szilárd alappal. Továbbá, ha a szoftver módosításra kerül a jövőben, még fontosabb, hogy egy logikai alapot kövessen, hogy elválassza a szervert a klienstől. Ennek az a célja, hogy ha egy programozót felvesznek, és nem tudja tisztán értelmezni a program dinamikáját, működését, létrehozhat vagy kicserélhet valamit, ami biztonsági hiba hozzáadásához vezethet. Még a legjobb tervezés mellett is állandóan fennáll a lehetőség, de minél inkább szabványosított a tervezés, annál kisebb az esély az előfordulásra.