Autor Zpráva
hal_sk
Profil
Zdravím.
V posledných dňoch som sa začal zaujímať, ako svoje weby zabezpečiť proti možným útokom. Prečítal som si nejaké články z netu, a dovolím si sem napísať čo som z toho pochopil a nepochopil. Vy ma prosím opravte a doplnte.
Takže največšou hrozbou sú SQL injection útoky a XSS útoky.
Obrana proti SQL injection - treba kontrolovať vstupné reťazce.
Obrana proti XSS - treba kontrolovať výstupné reťazce.

Kontrola vstupných reťazcov:
Tuto som zmätený, lebo som sa v spomínaných článkoch stretol s veľkým množstvom ochranných funkcií, ako napr: addslashes, mysql_real_escape_string, get_magic_quotes_gpc, atď... a nevyznám sa v nich.
Povedzme že ja sa budem brániť takto: u číselných typov budem kontrolovať či je daný reťazec číslo, ak nie tak sa GET neodošle.
Textové vstupné reťazce: bude stačiť funkcia ktorá nahradí (') za (") ? Lebo iné znaky, ktoré sa dajú využiť na útok, ako napr. (%,?), budem potrebovať povoliť, lebo užívatelia budú budú písať na web články, ktoré toto môžu obsahovať.

Kontrola výstupných reťazcov:
Ochrana spočíva napr. v požití funkcie htmlspecialchars pre každý výstupný reťazec.

Stačí mi taká ochrana ako som ja navrhol?
Vďaka za prípadné vaše reackie.
Werewolf
Profil
Nemám co doplnit. Možná upozornění na nutnost limitu do odeslání dalšího příspěvku, captcha...

Mohlo by se to přeložit (:-)) a přidat do FAQ.
Alphard
Profil
hal_sk:
Je potřeba escapovat citlivě na kontext. Viz Escapování - definitivní příručka » phpFashion
Jinak jste zapomněl na csrf.

Werewolf:
Mohlo by se to přeložit (:-)) a přidat do FAQ.
A prvně odpovědět a vysvětlit, ne? Vždyť je tam víc otázek než odpovědí :-)
hal_sk
Profil
Alphard:
Je potřeba escapovat citlivě na kontext. Viz Escapování - definitivní příručka » phpFashion

Mohol by mi prosím niekto "polopate" vysvetliť čo je to to escapovanie? Z daného článku som to nepochopil :-(
RockFire
Profil
Jestli se nemýlím, escapování změní /', " a ' na ", aby nemohlo proběhnout XSS. Ošetří se funkcí (při zápisu do db) mysql_real_escape_string();
Alphard
Profil
hal_sk:
Mohol by mi prosím niekto "polopate" vysvetliť čo je to to escapovanie?
Obecně bych řekl, že jde o "neutralizaci" speciálních znaků v daném prostředí. V html to může <, v sql '. Konkrétní náhrady vás ani nemusí moc zajímat, stačí použít správnou funkci a tu najdete právě v odkázaném článku.

Občas bohužel řešení není tak jednoduché, mnoho wysiwyg sype rovnou html, pak nezbyde nic jiného než ho rozebrat a zkontrolovat (strip_tags() většinou nestačí kvůli různě povoleným/zakázaným parametrům).
Mikeses
Profil
naco ochrana ??? nici web neni tak dokonaly aby byl treba hacknut
vynalezce
Profil
Mikeses:


nici web neni tak dokonaly

o tom by se dalo polemizovat (minimalne v oblasti bezpecnosti webovych aplikaci)


naco ochrana ??? nici web neni tak dokonaly aby byl treba hacknut

cim mene der je na webu tim lepe (tim tezsi je najit chybu a tim mene lidi se tam dostane)
AM_
Profil
Mikeses:
děkujeme za hodnotný příspěvek, ale pokusy o hackování různých webů jsou bohužel součástí naší reality.
hal_sk:
Některé věci tam máš dost obecně, např. kvůli XSS je důležité escapovat řetězce předávané javascriptu, a to ne pouhým addslashes, ale dát pozor na </script>; představ si, že ti někdo do skriptu:
<script type="text/javascript">alert('<?php echo addslashes($message); ?>');</script>
podstrčí třeba "</script>Haha, hacknuto".
Korektní escape pro JS vypadá takto (převzato ze Smarty):
return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
hal_sk
Profil
AM:
Nestačí na to strip_tags ?
imploder
Profil
Alphard:
A prvně odpovědět a vysvětlit, ne? Vždyť je tam víc otázek než odpovědí :-)
Mohlo by se to dát do FAQ ještě společně s přehledem různých ochran proti botům, dost to spolu souvisí.
AM_
Profil
hal_sk:
To není správné řešení, cílem je dostat do javascriptu libovolný řetězec aby nedošlo k chybě a nevytvořila se potenciální díra, ne to nějak ošmikat, aby to fungovalo.
Představ si, že chceš javascriptem třeba prohnat hlášku "Tagy <td> a <th> jsou buňky tabulky" - uživateli se zobrazí "Tagy a jsou buňky tabulky" - hloupé, ne?
hal_sk
Profil
AM:
To je pravda. Na to sa budem musieť pozreť.
[b onClick="alert('hacked')"]Skúška (klik)[/b]
hal_sk
Profil
Podľa skúšky nadomnou, BBcode ignoruje atribúty v tagoch. Asi s tým mojim portálom prejdem na BBcode, bude menej problémov. Práve som totiž u mňa objavil takúto dieru :-)
imploder
Profil
Alphard:
Občas bohužel řešení není tak jednoduché, mnoho wysiwyg sype rovnou html, pak nezbyde nic jiného než ho rozebrat a zkontrolovat (strip_tags() většinou nestačí kvůli různě povoleným/zakázaným parametrům).
Proč by měl být problém s tím, že editor sype rovnou HTML?

Escapovat se dá těmito dvěma funkcemi (jsou na to dělané):
- před vložením do SQL dotazu: addslashes() - escapuje znaky pro bezpečné vložení řetězce do SQL
- před vypsáním do stránky: htmlspecialchars() - nahradí znaky <, > a podobné HTML entitami (taky je to v podstatě escapování)

Není dobré různé způsoby escapování míchat; znaky, které se escapují v obou, by pak byly escapované dvakrát, tzn. text by se poškodil.
Alphard
Profil
imploder:
Mohlo by se to dát do FAQ ještě společně s přehledem různých ochran proti botům, dost to spolu souvisí.
To možná ano, ale asi se shodnem, že první příspěvek kromě neúplného výčtu nemá skoro žádnou informační hodnotu. Momentálně se mi moc nechce sepisovat článek o zabezpečení, ale mohl bych najít důvěryhodné stránky a aspoň je odkázat se stručným komentářem, uvidíme.

před vypsáním do stránky: htmlspecialchars() - nahradí znaky <, > a podobné HTML entitami
To právě nesmí, wysiwyg editor je tam proto, aby se vkládaný text formátoval, rozhodně není cílem odstranit z něho všechny tagy. Zároveň musí být ale text chráněn proti podstrčení onClick="alert()" apod., poškozenému html apod.
Pak to dopadá tak, že se zvolí povolené tagy a vše ostatní musí pryč, samozřejmě se musí i opravit/vymazat poškozené html (neuzavřené tagy, apod.).
Např.
$safeTags = array(
        'a'         => array('href', 'title'),
        'acronym'   => array('title'),
        'b'         => array(),
        'br'        => array(),
        'cite'      => array('title'),
        'code'      => array(),
        'em'        => array(),
        'i'         => array(),
        'strong'    => array(),
        'sub'       => array(),
        'sup'       => array(),
        'q'         => array(),
        'small'     => array(),
        'p'         => array(),
        'table'     => array(),
        'tbody'     => array(),
        'th'        => array(),
        'tr'        => array(),
        'td'        => array(),
        'del'       => array(),
        'dl'        => array(),
        'dt'        => array(),
        'dt'        => array(),
        'span'      => array('style', 'title'),
        'h1'        => array(),
        'h2'        => array(),
        'h3'        => array(),
        'h4'        => array(),
        'h5'        => array(),
        'h6'        => array(),
        'hr'        => array(),
        'img'       => array('title', 'src', 'border', 'alt'),
        'ul'        => array(),
        'ol'        => array(),
        'li'        => array(),
        'strike'    => array(),
        'blockquote'=> array(),
);
AM_
Profil
imploder:
ono ani není důvod escapovat něco dvakrát, a pokud ano, tak se text nepoškodí, např. \ se bude v reguláru zapsaném v PHP mezi uvozovky " " escapovat opravdu dvakrát a vznikne z něj \\\\ :)
Jinak vyhnul bych se formulaci "escapovat se dá těmito dvěma funkcemi", nebo bych alespoň doplnil, že rozhodně ne "jen těmito". Jsou i další funkce, např. mysql_(real_)escape_string, a jak jsem uvedl, pro korektní oescapování pro předání řetězce JavaScriptu PHP bohužel asi vestavěnou fci nemá.

Je nutné si uvědomit, co to escapování vlastně je: obecně je to "zabalení" řetězce tak, aby jej příjemce přijal v původní podobě a nepřimíchaly se tam řídící znaky příjemce.
Tím, že na webu používají programy více jazyků, často v jednom souboru - PHP, HTML, CSS (tam ale řetězce prakticky nejsou, to jen pro úplnost), JavaScript, SQL, regulární výrazy a našly by se i další; vzniká v escapování trochu zmatek.
Dobrý příklad je s těma regulárama, kdy řetězec zapsaný jako řetězcová konstanta PHP je nejprve zpracován PHP interpreterem, kvůli kterému musí být oescapován, PHP interpreter si jej "rozbalí", takže engine regulárních výrazů dostane řetězec rozbalený z prvního obalu, ale i tomuto engine musíme sdělit, které znaky jsou řídící a kde chceme vyjádřit ten znak jako takový.

P.S. důležité je escapovat jen tam, kde je to potřeba, a řetězce uchovávat pokud možno ve své původní podobě. Častý problém je právě v tom, že sem tam něco oescapované je a sem tam není, ono to většinou funguje, ale pak se tam přimíchá špatný znak a problém je na světě.
imploder
Profil
Alphard:
Aha, takže jde o případ, kdy si do WYSIWYG editoru načtu cizí kód a potřebuju ho upravit, ale vynechat z něj případný vadný nebo nepotřebný/škodlivý kód.

AM:
ono ani není důvod escapovat něco dvakrát, a pokud ano, tak se text nepoškodí, např. \ se bude v reguláru zapsaném v PHP mezi uvozovky " " escapovat opravdu dvakrát a vznikne z něj \\\\ :)
Nepoškodí se tak, že by se ztratila informace, ale poškodí se tak, že není stejný. Pokud se pak interpretují ty escape sekvence všechnz a ve správném pořadí, tak se nic neděje.

Dobrý příklad je s těma regulárama, kdy řetězec zapsaný jako řetězcová konstanta PHP je nejprve zpracován PHP interpreterem, kvůli kterému musí být oescapován, PHP interpreter si jej "rozbalí", takže engine regulárních výrazů dostane řetězec rozbalený z prvního obalu, ale i tomuto engine musíme sdělit, které znaky jsou řídící a kde chceme vyjádřit ten znak jako takový.
Na to má PHP jednoduché řešení: pokud řetězec neobsahuje apostrofy, dá se napsat místo mezi uvozovky mezi apostrofy - tam se escape sekvence neinterpretují, všechno až do dalšího apostrofu se bere jako čistý obsah řetězce.
AM_
Profil
imploder:
Na to má PHP jednoduché řešení: pokud řetězec neobsahuje apostrofy, dá se napsat místo mezi uvozovky mezi apostrofy - tam se escape sekvence neinterpretují
ne tak docela - mezi apostrofy se dá vecpat další apostrof sekvencí \' :) pak je ovšem někdy nutné escapovat i \ na \\, jiné sekvenceo to jak říkáš nevezme a pokud za \ ale nepokračuje jedna z těchto sekvencí, PHP ho interpretuje jako \, takže to "skoro funguje".
Nicméně samozřejmě, inteligentní člověk píše reguláry do apostrofů, uváděl jsem to jen pro příklad vícenásobného escapování.

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0