HTML tag jako odjištěná zbraň
V článku „Bezpečnost především – zamezení interpretace HTML kódu“ jste se mohli dovědět, jak nebezpečný může být uživatel, je-li mu například na diskuzním fóru napsaném v PHP vložena do rukou zbraň v podobě formátování příspěvku pomocí XHTML elementů. Jaké jsou tedy „bezpečné“ možnosti formátování příspěvků na různých typech diskuzních fór?
Jenom pro připomenutí, dejme tomu, že uživateli dovolíme používat tag <b> a zbytek budeme filtrovat pomocí funkce string strip_tags(string retezec,[string povolene_tagy])
. Pak následující kód způsobí katastrofu:
<b style=“width: 100%;“ onmouseover=“document.location=’http://www.interval.cz'“>nějaký text</b>
Tento zápis nechá strip_tags
bez povšimnutí. Jak určitě tušíte, vznikne tak řádek přes celou obrazovku, který vás po přejetí myší odešle na libovolný jiný web, což rozhodně žádného webmastera příliš nepotěší. Je sice pravda, že 95 % vašich návštěvníků určitě nikdy nenapadne něco takového do fóra zapisovat, přesto nemůžeme ani tuto možnost nechat bez povšimnutí, neboť v podstatě umožňuje na stránce spouštět libovolný JavaScript! Další, tentokrát již pravděpodobnější nevýhodou XHTML tagu, je dodržování W3C standardů. Uživatele samozřejmě příliš nezajímá, že jím vložené tagy nejsou podle dané normy. Často se tak stává, že vloží např. <B> namísto <b>, nebo jej neuzavře. Kapitolou samou pro sebe jsou pak vkládané odkazy <a>, které mohou kompletně narušit funkčnost fóra, zůstanou-li neukončeny. O tom, že uživatel často neuzavře argument do závorek, jak velí XHTML norma, mluvit netřeba.
Vlastní syntaxe
Jednou z možností řešení tohoto problému je pečlivá kontrola odeslaného příspěvku. To však nepovažuji za optimální řešení, neboť takto budete muset naprogramovat kontrolu počítající i s tou nejméně pravděpodobnou variantou, kterou si uživatel jenom může vymyslet. Proto je mnohem výhodnější a hlavně bezpečnější vytvořit vlastní syntaxi formátování příspěvku. Daná syntaxe by měla být co nejjednodušší a nejsrozumitelnější a uživatel by s ní měl být dobře obeznámen.
Navrhněme si takovou syntaxi:
- {b}text{/} ~ vypíše text tlustě
- {i}text{/} ~ vypíše text kurzívou
- {adresa}text{/} ~ vytvoří z textu odkaz na danou adresu (řetězec adresa musí začínat
http://
)
Naším dalším úkolem je napsat PHP skript, který dané formátovací značky převede na XHTML tagy.
Některé funkce PHP pro práci s textem
Nejdříve si připomeňme některé funkce PHP pro náhradu části textu za jiný. Nejjednodušší je string str_replace(string vzorek, string nahrada, string retezec)
, která nahradí všechny výskyty řetězce vzorek
řetezcem nahrada
v řetězci retezec
. Další funkce jsou založeny na regulárních výrazech:
string ereg_replace (string vyraz, string nahrada, string retezec)
string eregi_replace (string vyraz, string nahrada, string retezec)
Obě funkce pracují podobně jako zmíněná str_replace
. Argument vyraz
ovšem tentokrát není statický text, ale regulární výraz (o regulárních výrazech pojednává např. článek Regulární výrazy v PHP (1.)). Funkce tedy vyhledá v řetězci retezec
všechny části odpovídající regulárnímu výrazu vyraz
a nahradí je řetězcem nahrada
. Funkce eregi_replace
navíc není citlivá na malá a velká písmena.
Poslední funkci, kterou zde zmíním, je mixed preg_replace (mixed vyraz, mixed nahrada, mixed retezec)
. Funkce pracuje podobně jako ereg_replace
, ovšem všechny argumenty mohou být pole řetězců, což znamená, že lze najednou provést náhradu pro všechny položky pole retezec
najednou. Zároveň lze nadefinovat i více výrazů a jim příslušné náhrady (intuitivně n-tému prvku pole vyraz
přísluší n-tý prvek pole nahrada
).
Funkci str_replace
použijeme, pokud předem známe přesné znění podřetězců, které potřebujeme vyhledat a nahradit. Naopak funkce používající regulární výrazy jsou výhodné, pokud známe pouze formát vyhledávaných podřetězců, nikoli jejich přesné znění. Nutno dodat, že str_replace
je mnohem rychlejší než její protějšky pro regulární výrazy, a proto by měla být použita pokaždé, kdy je to jen možné.
Implementace navržené syntaxe
Pro implementaci použijeme regulární výrazy. Začněme zvýrazněným textem:
$text=ereg_replace(„{b}([^{}]*){/}“,“<b>\\1</b>“,$text);
Hledáme vzorek odpovídající regulárnímu výrazu {b}([^{}]){/}
(posloupnost znaků {b} následována libovolným řetězcem neobsahující složenou závorku a zakončená {/}), který nahradíme <b>\\1</b>
(\\1 značí obsah části regulárního výrazu vymezený kulatými závorkami v prvním argumentu funkce). Tento postup můžeme udělat ještě více „odolným“, pokud budeme předpokládat, že se uživateli může vloudit mezera do složené závorky a že může použít velké písmeno namísto malého:
$text=eregi_replace(„{ *b *}([^{}]*){ */ *}“,“<b>\\1</b>“,$text);
Regulární výraz { *b *}
představuje „složenou závorku, žádná nebo více mezer, znak „b“, žádná nebo více mezer a složenou závorku“. Použitím funkce eregi_replace
jsme uživateli dovolili použít velká písmena oproti námi definované syntaxi.
Obdobným způsobem vyřešíme text psaný kurzívou:
$text=eregi_replace(„{ *i *}([^{}]*){ */ *}“,“<i>\\1</i>“,$text);
Vkládané odkazy jdou vyřešit dvojím způsobem. Jednak můžeme prohledávat celý příspěvek, vyhledávat odkazy a automaticky je transformovat na XHTML tagy. Zabývejme se ale naší speciální syntaxí. PHP kód je následující:
$text=eregi_replace(„{ *(http://[^}]+) *}([^{}]+){ */ *}“,“<a href=\“\\1\“>\\2</a>“,$text);
Jak již bylo řečeno, předpokládáme, že uživatel svůj odkaz začne řetězcem http://
. Do prvních kulatých závorek jsme tedy uzavřeli samotnou adresu, do druhých text, který se stane odkazem.
UBB-code
Nyní se podívejme na speciální syntaxi v praxi. Jeden z nejznámějších a nejlepších systémů Ultimate Bulletin Board system (UBB) používá pro formátování příspěvků svůj vlastní UBB-code. Jde o syntaxi podobnou HTML používající hranaté závorky místo špičatých. Zde je ukázka:
- [B]tučný text[/B]
- [I]kurzíva[/I]
- [URL=http://www.interval.cz]odkaz[/URL]
- [EMAIL]email[/EMAIL]
- [IMG]adresa nějakého obrázku[/IMG]
- [QUOTE]citát[/QUOTE]
- …
Výhody a nevýhody speciální syntaxe
Výhody jsou myslím zřejmé. Uživatel nemá možnost vkládat spustitelný, resp. interpretovatelný obsah do svých příspěvků, protože je plně pod vaší kontrolou, jak se kód zapsaný ve speciální syntaxi převede na XHTML. Další výhodou je, že špatně zapsaná část kódu nijak neohrozí vaši aplikaci. Zatímco např. neukončený odkaz způsobí pohromu, jeho protějšek ve speciální syntaxi se pouze zobrazí ve výsledném výpise fóra, což z hlediska funkčnosti fóra nijak neuškodí. A navíc, pokud je uživateli umožněno svůj příspěvek upravovat (což je asi reálně uskutečnitelné pouze na fórech s registrací), může si chybné zapsání syntaxe uvědomit a opravit. Snad jedinou skutečnou nevýhodou tohoto postupu je nutnost uživatele dobře seznámit se syntaxí a zařídit, aby byla „po ruce“ např. i přímo při psaní příspěvku.
Speciální syntaxe je asi nejlepší možnost, jak co nejlépe zabezpečit diskuzní fórum a zároveň dovolit uživateli formátovat své příspěvky.
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Gaming na HDR monitoru: Stojí to za to?
12. srpna 2024 -
Optimalizace a zlepšení výkonu kódu: tipy a triky
14. srpna 2023 -
Vlastní web: Jak nainstalovat WordPress?
24. června 2024
Nejnovější
-
Jak rozšířit úložiště Macu za pětinovou cenu?
16. prosince 2024 -
Nové trendy v doménách pro osobní projekty – DIY, LIVING a LIFESTYLE
9. prosince 2024 -
Jak chránit webové stránky před Web/AI Scrapingem
27. listopadu 2024 -
Jaký monitor je nejlepší k novému Macu Mini?
25. listopadu 2024