Ako (si nechať) hacknúť webovú aplikáciu?
V predchádzajúcej lekcii, Ako sa brániť proti SQL injection , sme si uviedli spôsoby, ako pred útokom SQL injection svoju aplikáciu chrániť.
Tento článok sa vzťahuje k marcovému přednáškovému zraze, kde som hovoril o najbežnejších bezpečnostných chybách webových aplikácií.
Tu na ITNetwork existuje niekoľko detailnejších článkov popisujúci jednotlivé chyby. Ja by som rád zhrnul tie najčastejšie.
Napísal som testovaciu aplikáciu nazvanú Super secure social network, ktorá má slúžiť ako ukážkový príklad zle napísané PHP aplikácie, z ktorej tu čerpám príklady. Tieto chyby sa dajú urobiť aj v iných jazykoch, tu budem však používať príklady z PHP.
Neošetrené užívateľské vstupy
Väčšina chýb a bezpečnostných dier vzniká, ak útočník pošle na stránky vstup, ktorý programátor neočakával a neošetrili. Ten môže prísť z mnohých zdrojov:
- GET
- POST, telo požiadavke
- Upload súborov
Je potrebné myslieť na to, že nad tým, čo používateľ posiela v požiadavke na server, má kontrolu sám užívateľ. Ak vykonávate akékoľvek legalizácie v rámci prehliadača, je následne potrebné vykonať je aj na serveri. Napr. pokiaľ užívateľ pošle formulár, mal by server vedieť pracovať so situáciou, kedy dostane iná políčka, než očakával. Toho pekne využíva chyba Mass assignment.
SQL injection
Predstavme si, že vytvárame sociálna sieť. Pri každom príspevku je like tlačidlo a po jeho stlačení budeme chcieť vložiť do tabuľky users_posts_like používateľov like. Na to programátor naivne napíše podobný kus kódu:
"INSERT INTO users_posts_like (user_id,post_id) VALUES ({$_SESSION['id']},{$_GET['like']})"
<! - context
/-->
Ten bude fungovat dobře, dokud uživatel v GET parametru nepošle něco jiného, než předpokládané číslo. Co kdyby uživatel poslal např. "?like=12); TRUNCATE TABLE users_posts_like;/*"
Ten se vyhodnotí jako dva různé dotazy:
\--
INSERT INTO users_posts_like (user_id,post_id) VALUES (123,12); TRUNCATE TABLE users_posts_like; /*)
Prvý vykoná to, čo programátor očakáva. Druhý je úplne podstrčené útočníkom. Môže ním vykonať čokoľvek v databáze. V tomto prípade zmaže obsah celej tabuľky users_posts_like.
Prepared statements
Ak používame PDO, či inú DB vrstvu, umožňuje nám používať tzv. Prepared statements. Jedná sa o techniku, kedy dotaz rozdelíme na dve časti - štruktúru a dáta.
Najskôr definujeme štruktúru dopytu a miesto dát dosadíme premenné:
$query = $db->prepare("INSERT INTO users_posts_like (user_id,post_id) VALUES (:user_id,:post_id})");
<! - context
/-->
Následně řekneme, jaká data mají v proměnných být: \--
$query->bindParam(':user_id', $_SESSION['id']); $query->bindParam(':post_id', $_REQUEST['like']); $query->execute();
Ak máme v PDO vypnuté EMULATE_PREPARES, vykoná sa dotaz na 2 časti. Najskôr je databázu poslaná štruktúra a až potom dáta, ktoré nie sú v žiadnom prípade braná ako štruktúra dotazu.
Ak máme EMULATE_PREPARES zapnuté PDO nám parametre automaticky escapuje.
Uvádzacích
Ak použáváme zastarané mysql funkcie, môžeme vstupy od užívateľa ručne ošetriť pomocou "mysql_real_escape_string": http://php.net/...e-string.php. Toto riešenie je však náchylné k urobeniu chyby.
XSS
Je skratka pre Cross-site scripting. Táto bezpečnosťou diera nespúšťa kód na serveri, ale JavaScript na strane užívateľa. Predstavme si, že na našej sociálnej sieti máme príspevky, ktoré sa na stenu vypisujú takto:
$query = $db->prepare("SELECT content FROM posts"); $query->execute(); $result = $query->fetchAll(); foreach($result as $row){ echo $row['content']; echo '<hr/>' }
Ak niekto do príspevku umiestni napr .:
ahoj <script>alert("baf!");</script>
Bude príspevok pôsobiť ako obyčajné ahoj. Avšak všetkým ľuďom na stránke bude pri príchode vyskakovať "baf!". To by bolo skôr otravné než nebezpečné. My ale pomocou skriptu môžeme vykonávať naozaj veľa vecí napr .:
- Nastaviť Listener na políčko mena a hesla a to si posielať na vlastný server.
- Užívateľa prinútiť zadať mail v domienke, že ho posiela napadnutá stránke.
- Môžeme celú stránku úplne prerobiť.
- Môžeme si od užívateľa poslať všetky cookies, čo nie sú HttpOnly.
Akonáhle objavíme XSS dieru, môžeme stránku narušiť mnohými kreatívnymi spôsobmi. Dokonca existuje nástroj, ktorý sa dá použiť na vzdialené ovládanie otvorených napadnutých stránok - Beef framework.
Uvádzacích
Nejjednosušší cestou, ako túto chybu neurobiť, je uvádzacích. K tomu nám pre HTML v PHP slúži funkcia htmlspecialchars. Problém je, že keď escapujeme v inom kontexte (napr. Atribútu), musíme použiť inú funkciu či dokonca ich kombináciu. Je veľmi ľahké pomýliť sa a XSS dieru urobiť omylom.
Šablónovacích systémy
Najlepšou cestou, ako sa tejto chyby nedopustiť, je použiť nejaký šablónovacích systém v PHP napr. Twig, Smarty či Latte.
CSRF
Cross-site Request Forgery je prevedenie požiadavke za iného užívateľa bez jeho vedomia. Predstavme si, že like tlačidlo na našej sociálnej sieti bude vyzerať takto:
<a href="?like=27">Like</a>
Čo keby sme vyrobili link pomocou skracovače odkazov smerujúce na supesecuresocialnetwork.fake / wall? Like = 27 a ten poslali na túto siet. Každý, kto by na daný odkaz klikol, by automaticky olikoval nás príspevok.
A čo keby sme kreatívne skombinovali CSRF a XSS. Miesto postu, čo hádže Baf !, by sme poslali post:
ahoj <img src="https://supesecuresocialnetwork.fake/wall?like=27" style="display:none"/>
V tejto chvíli by používatelia likovali náš príspevok bez toho, aby vykonali akúkoľvek akciu, okrem zobrazenia najnovších príspevkov.
Pošta vs. GET
Podstata tejto chyby spočíva v tom, že môžem vykonať akciu pomocou metódy GET. Správne navrhnutá webová aplikcace by mala meniace akcie posielať iba pomocou metódy POST (prípadne PUT, DELETE, ...). Metóda GET by sa mala používať len pre požiadavky, keď informácie tečú zo servera ku klientovi a nič na serveri nemení (okrem logov a zaznamenanie návštevnosti).
Ďalšie
Veľa vecí som tu nespomenul a spomeniem v dnešnej prednáške a následne ich doplním sem alebo do ďalšieho článku:
- clickjacking
- Zlé a správne ukladanie hesiel
- HTTP (S) a downgrade útoky a obrana pomocou HSTS
- DDoS
- phishing
V ďalšej lekcii, Útok Clickjacking a ako sa pred ním brániť , sa zoznámime s útokom Clickjacking a uvedieme si spôsoby, ako sa pred týmto typom útoku brániť.