Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Jak penetrují mladí chlapci?

Mladí chlapci se musejí vymezovat proti autoritám. Mají to v popisu práce. V diskusi neváhají nedostatek zkušeností nahradit sebejistotou a drzostí. Fakt hloupé to začíná být ve chvíli, kdy vlastně jen nahrazují.

Martin Klubal alias Emkei, administrátor serveru Soom.cz, se poměrně ostře pustil do Jakuba Vrány pod článkem o bezpečnostním auditu serveru Na volné noze. Na věci je pikantní, že Martin Klubal je Jakubův konkurent, neboť provozuje službu Pentester komerčně nabízející bezpečnostní audity webových aplikací.

Obdivuju Jakuba, s jakou trpělivostí se nechal penetrovat mladistvým script kiddie, já bych ho asi smazal hned v zárodku. Jakub je v tomto směru až hyperkorektní a jsem přesvědčen, že si tak poškozuje své jméno. Když totiž diskusi přečte neodborník, nemusí mu být úplně zřejmé, kdo je tady vlastně za diletanta. Čtenář potřebuje vodítko a proto vznikl tento článek.

Takže vězte: Martin Klubal alias Emkei je úplně mimo. Patří do sorty tzv. „bezpečnostních odborníků“, kteří tohoto sice hodně načetli, jenže při čtení vůbec nepřemýšleli. Vědí o spoustě útoků, ale nemají páru o technickém pozadí a neví, jak jim skutečně čelit. Na argumenty nejsou schopni reagovat jinak, než odkazováním na (dle jejich názoru) autoritativní zdroje, tedy v tom lepším případě, v tom horším se uchylují k osobním útokům. Dokážou však udělat výborný první dojem a ohromit množstvím znalostí. Že jsou jejich rady kontraproduktivní, se nemusí hned zjistit.

Emkei script

Ale zpět k diskusi. Emkei upozorňuje na útok upload null byte, který prý souvisí s nastavením direktivy magic_quotes_gpc a prý znemožňuje kontrolu nahraného obrázku na základě jeho přípony. Diskuse poté kráčí ve výše popsaných šlépějích, takže o upload null byte útoku nebo direktivě magic_quotes_gpc se od něj nedozvíme vůbec nic, zato se dočteme, že Jakub je blázen, stahovačný (sic!), líný hlupák a tak vůbec ;)

V jedné chvíli však Emkei neprozřetelně utrousí moudra a podělí se o kus PHP kódu. Ten by měl demostrovat zmíněný null byte útok, vtipné však je, že prakticky na každém řádku je nějaká chyba. Od méně závažných po naprosto fatální bezpečnostní díru:

if (strtolower(substr($HTTP_POST_FILES['obrazek']['name'], -4, 4)) == ".jpg") {
        $path= "upload/".urldecode($HTTP_POST_FILES['obrazek']['name']);
        if($ufile != none) {
                if(move_uploaded_file($HTTP_POST_FILES['obrazek']['tmp_name'], $path))
                        echo "Obrazek byl uspesne nahran na server";
                else
                        echo "Obrazek se nepodarilo nahrat na server";
        }
} else
        echo "Neplatny format obrazku";

Jen bodově:

  • pole $HTTP_POST_FILES bylo zavrženo už v roce 2001, jeho použití mě docela překvapilo
  • neověřuje existenci prvku $HTTP_POST_FILES['obrazek']['name'] a může tak generovat neošetřené E_NOTICE
  • neověřuje, že prvek $HTTP_POST_FILES['obrazek']['name'] je řetězec a může tak generovat neošetřené E_NOTICE (viz <input type="file" name="obrazek[]">)
  • urldecode() nemá v kódu co dělat. Pokud budete uploadovat soubor nazvaný třeba 70%absinth.jpg, na straně serveru byste dostali 70«sinth.jpg
  • urldecode() je místo, kde se zcela uměle vytváří díra „upload null byte“
  • podmínka if($ufile != none) pracuje s nedefinovanou proměnnou $ufile a nedefinovanou konstantou none
  • kód neřeší situaci, kdy $ufile == none, ať už je tím myšleno cokoliv
  • ke složce upload přistupuje relativně, takže se může chovat velmi nepředvídatelně
  • ale hlavně: dovoluje přepsat jakýkoliv jpg na webovém serveru, tedy i mimo adresář pro upload! (např. %2e%2e%2fobr.jpg)
  • kvůli uměle vytvořené „upload null byte“ díře dovoluje přepsat jakýkoliv soubor na webu (např. .htaccess%00.jpg)

Všechny tři řádky obsahující konstrukci echo se zdají být bez problému. Gratulujeme!

Na závěr bych Martinovi vzkázal jeho vlastní slova: chtel bych videt hlupaky, co ti za to tvoje bezpecnostni skoleni plati bezmala 5 000,– Kc. venuj se dal php a neprodavej lidem falesny pocit bezpeci v podobe amaterskych bezpecnostnich auditu… A firmám, které Pentester uvádí ve svých referencích (např. Webnode, Web4ce) doporučuji, aby si nechaly udělat audit také jinde.

clock 9. 8. 2009 pencil PHP comments Komentáře: 80


Orgasmy PHP 5.3 nevítají

Přichází trošku jako opozdilec, pro kterého včera večer byla přichystána velkolepá oslava, ale dnes už se hosté rozešli domů. Před rokem a půl byl internet plný článků o klíčových novinkách v PHP 5.3, po neustálém odkládání termínů a méně příjemných změnách nadšení vychladlo.

5 – 4 – 3 – 2 – 1 DOWNLOAD!

Jaké jsou novinky? Podstatné. Vezmu to podle důležitosti:

To klíčové přijde v následujících týdnech: jak rychle se PHP 5.3 rozšíří? Vzhledem k tomu, že bylo vyvíjeno jako přirozený nástupce řady 5.2 bez zpětně nekompatibilních změn, šance na brzké rozšíření rozhodně má. Nicméně si myslím, že hostéři budou čekat, až vyjde následující setinková verze. Jako když se u Windows čekává na první service pack.

Historie jim přitom dává za pravdu:

  • PHP 5.0.0, které vyšlo s rozdílem 14 dní právě před pěti lety, bylo použitelné cca od verze 5.0.3.
  • PHP 5.1.0 existovalo pouhé 4 dny a bylo nahrazeno 5.1.1, za dva týdny 5.1.2.
  • PHP 5.2.0 bylo opět případem zabugované verze, kde smutnou roli sehrál Debian.

(Totiž Debian Etch má tuto verzi předinstalovanou a nepochopitelný konzervatismus správců vede k tomu, že odmítají PHP updatovat, bo „jen to, co je v Debianu, je stabilní.“)

Přeji PHP 5.3 rychlý a úspěšný nástup do světa!

clock 30. 6. 2009 pencil PHP comments Komentáře: 13


Docela šokující čísla, že?

Zajímá vás, kolik vývojářů skutečně stojí za slavými projekty, bez marketingového mlžení? Pokusím se vyvrátit jeden mýtus, který někdy zaznívá proti Nette Framework, ale je docela možné, že vás tím připravím o iluze. Čtěte proto jen na vlastní nebezpečí!

O jaký jde mýtus? Pod Jakubovým článkem o vývoji open source projektů padl komentář:

Přesně tohle (tj. velmi malý počet vývojářů) je důvod proč dělám v Zendu a ne v Nette. Nette je skvělé protože ho dělá David. Jakmile s tím přestane, tak půjde do kytek i kdyby mělo komunitu sebelepší.

Já naopak musím říct, že projekt může zakladatele přežít jen tehdy, pokud sebelepší komunitu má. Nette Framework je svou komunitou už pověstný. Dovolím si zopakovat slova z minulého článku: podívejte se na české fórum kde je 9000 příspěvků a zkuste srovnat s jinými projekty. Nebo navštivte Poslední sobotu a zjistíte, že fórum je vlastně jen špičkou ledovce – na Sobotách probíhají zcela seriózní prezentace prací na dokumentaci, screencastech, vlastních komponentách atd. (Chystám články týkající se těchto jednotlivých počinů a jejich autorů.)

Ale vraťme se k počtu klíčových vývojářů u jednotlivých projektů. Obvyklá představa, že za každým významným projektem stojí početný tým vzájemně nahraditelných vývojářů, začala brát za své, když před dvěma lety vyšla zpráva, že projekt Thunderbird opouštějí oba hlavní vývojáři. Ano, zarážející je už to slůvko „oba“. Odchod pouhých dvou vývojářů Scotta MacGregora a Davida Bienvenu způsobil, že nad celým projektem se začala stahovat mračna.

Dejme to do souvislosti se zajímavými čísly, které nabízí server Ohloh. O projektu Thunderbird mi prozradil, že má úctyhodných 24073 commitů (commit je jeden příspěvek do kódu od jedné osoby). Přičemž na ty dva zmíněné vývojáře připadá 30 % commitů:

Opakuji: celých 30 % vývoje Thunderbirdu obstarali dva programátoři, jejichž odchod může být pro projekt smrtelný.

Nebudu chodit kolem horké kaše a podívám se stejnou metodikou na zoubek Zend Framework. Na obří framework, či spíše knihovnu, za jehož popularitou stojí jméno společnosti Zend a pro nějž hovoří „stovky vývojářů“ + několik „placených“. Nechme promluvit čísla:

Ano, 52 % frameworku je práce čtyř lidí. A pozor: na 2 hlavní vývojáře připadá 32 % frameworku, tedy situace je ještě malinko „nebezpečnější“ než v případě Thunderbirdu. Přesto nepochybuji, že pokud ty dva vývojáře srazí tramvaj (nebo šalina), vývoj frameworku by sice na nějakou dobu ustrnul, ale bude pokračovat dál.

Zend Framework přitom patří ještě mezi ty méně ohrožené projekty. Co třeba nesmírně slavné Ruby on Rails? Na grafu vidíte poměr commitů dvou hlavních vývojářů:

Ano, to je zásadní skok oproti předchozím projektům. Už pouhým dvěma vývojářům patří majorita. A ptám se: je snad Ruby on Rails odmítané proto, že by mohla Davida Heinemeiera Hanssona srazit šalina? Nebo naopak se bere jeho vize a pevné uchopení projektu jako výhoda? A obává se někdo, že ti dva nejsou placení vývojáři?

Když už brousíme mimo PHP, podívejme se na nejslavnější framework pro Python – Django:

O čtyři procenta víc než v předchozím případě. Bez dalšího komentáře.

Tak zpět do PHP luhů a hájů. Kromě Zend Framework a Nette Framewok se u nás těší největší popularitě asi CakePHP. Podle statistik jde o dílo tří hlavních vývojářů:

Ještě bych měl zmínit PRADO, kde téměř kompletní vývoj má pod palcem dvojice programátorů:

Z uvedených příkladů jde rozhodně o nejvyšší hodnoty. V tomto případě bych si už netroufl paušálně tvrdit, že by projekt pokračoval navzdory odchodu dvou vývojářů pod tramvaj – musel bych nejprve dobře znát komunitu kolem PRADO.

Ale ať skončíme pozitivně. Nakonec jsem si nechal projekt, který rozložením sil vychází jednoznačně nejlépe a tím je Symfony:

Nicméně i zde existuje dominantní jedinec, vůdce stáda, který převažuje nad ostatními.

Je vážně tak zle?

Ale vůbec ne! Pochopte prosím, že mým cílem nebylo vás strašit, ale pouze uvést do reality a demaskovat marketingové pozlátko. Raději zdůrazním, že

  • jednotlivá čísla vůbec nic nevypovídají o kvalitách projektů
  • nelze je použít ani jako vodítko při rozhodování

Naopak je přirozené a logické, že všechny projekty jsou dílem několika málo osobností. Tak je to na světě zařízené. A naopak, čím více lidí má právo commitovat, tím více se do kódu dostane balastu. Jak se dokáže ten který projekt vyrovnat se ztrátou vůdčích osob je vždycky nejisté. V případě Nette Framework mě těší vědomí, že konečně po pěti letech vývoje vím, že by se vyrovnat dokázal.

Doplnění: Karmi mi v komentářích připomněl důležitou věc, kterou jsem v článku opomněl a způsobil tak nedorozumění. Článek odkrývá skutečnost, že za úspěšnými projekty stojí vždy jen pár nesnadno nahraditelných osobností (úkolem marketingu je vytvořit opačný dojem). Je ale potřeba dodat, že u dobře fungujících open source projektů se pozice těchto osobností v čase mění. Nejprve jsou to výhradní autoři a programátoři, aby se časem přesunuli do pozice těch, kteří projekt vedou a dávají mu vizi. A třeba úplně přestanou psát kód.

clock 2. 6. 2009 pencil PHP comments Komentáře: 36


Odmítám OpenID

Články nebývají kontroverzní svým obsahem, ale nevhodnou dobou zveřejnění. Ještě než padne první věta, že OpenID je uměle vyhypovaná záležitost, poprosím všechny, kterým to způsobí rudé vidění nebo přezíravý povzdech, aby se pokusili článek přečíst se snahou porozumět.

OpenID je technologickými fandy uměle vyhypovaná záležitost. Připomíná vzestup Firefoxe, prohlížeče, který běžným uživatelům nechyběl, ale který jim jejich počítačově zdatné ratolesti instalovaly místo Exploreru, a to z důvodů, které spíš než v logice měly oporu v přesvědčení. Abych nebyl špatně pochopen: je moc dobře, že se Firefox dostal tam, kde nyní je, ale v době vzestupu to nebyla killer application, dokonce ani lepší volba, pro masového uživatele to byl jen krapet pomalejší a hardwarově náročnější prohlížeč, který uměl zobrazit o něco méně stránek.

Co je vlastně OpenID? Je to technologie, která umožňuje lidem přihlašovat se na různé weby stejným loginem, bez opakovaných registrací a vymýšlení hesla. Zbavuje návštěvníky neoblíbených registračních a přihlašovacích formulářů. Hovoří se o ní jako o univerzální internetové občance. Přesto o ní mluví jen několik nadšenců a žádná revoluce se nekoná. Proč?

Uživatelská nepřívětivost

Dnešní prohlížeče velice usnadňují vyplňování klasických přihlašovacích i registračních formulářů. Nenabízejí však žádnou podporu pro přihlašování přes OpenID.

Registrační formulář představuje notoricky známý vzor, jehož vyplnění zvládá běžný uživatel jako samozřejmost (byť se mu to snaží řada webových tvůrců setsakramentsky zkomplikovat). Prohlížeče si hesla pamatují a celý proces přihlášení redukují na kliknutí na ikonku nebo tlačítko, neprobíhá-li automaticky zcela.

Vedle toho registrace přes OpenID je krokem do neznáma vyžadující značné úsilí. Poprvé jsem si to vyzkoušel na blogu asi největšího popularizátora OpenID u nás, Martina Malého, který běží na Drupalu. Registrace přes OpenID se skládala z mnohem více kroků, než registrace klasická, na některé obrazovky jsem nechápavě zíral a snažil se odhadnout, co se po mně probůh chce.

Čímž pochopitelně nekritizuju Martina, který byl z chování Drupalu taky nešťastný. Jde jen o ukázku toho, že Drupal vyvíjejí programátoři, nikoliv experti na použitelnost. Ano, tyto skupiny vnímám jako protikladné. Ano, sám jsem výjimka :-)

Další problém nastává při přihlašování. Prohlížeč nijak nespolupracuje, magická hůlka v Opeře nefunguje. Je potřeba kliknout na ovládací prvek přepínače, ručně vyplnit OpenID login, dostat se na stránky OpenID providera a tam se lze teprve přihlásit s hůlkou. Pokud se potřebujete přihlásit v okamžiku, kdy se chystáte odeslat komentář (což je prakticky ve 100% připadů), spáchá na vás Drupal ještě horší kulišárnu – komentář si musíte uložit do schránky, manuálně se přihlásit, poté znovu najít místo, na které reagujete a znovu komentář vložit.

Samozřejmě lituju toho, že jsem se s OpenID vůbec přihlašoval, a jelikož to nejde zvrátit, přestal jsem psát komentáře – pro Misantropa má OpenID nečekané pozitivum ;)

Implementace především

Říkáte, že pláču na špatném hrobě, že argumentace se netýká OpenID ale jedné zmršené implementace? Máte samozřejmě pravdu. Jde však o výbornou ukázku toho, jak slibná technologie může být zásadním krokem zpět z pohledu uživatelů.

Jsem přesvědčen o tom, že budoucnost OpenID závisí na podpoře za strany prohlížečů. Pokud přijdou s vestavěným OpenID přihlašováním na jeden klik, bude vyhráno. Aby stačilo přímo v prohlížeči nastavit svou identitu. Aby nedocházelo k žádným přesměrováním na providera, aby všechno proběhlo v rámci aktuální stránky, doprovázeno nanejvýš dialogovým oknem prohlížeče.

Podpora prohlížeče je klíčová i pro vývojáře webových aplikací. OpenID protokol je šíleně složitý, o schopnosti Běžného Programátora ™ napsat přívětivé chování webové aplikace si nedělám iluze. Pokud se však opráší cca koncept HTTP autentifikace, šikovně implementovat ho dokáže i začátečník.

Budou to prohlížeče umět? A kdy?

Bezpečnost (ještě víc) především

Musím zmínit ještě jednu filosofickou stránku. Dosud byla počítačová veřejnost vychovávána k tomu, aby na každém webu používala jiné heslo. Sám jsem to zvládl jen díky udělátku a dnes skutečně mám všude jiné a velmi silné heslo (a jsem tomu rád).

OpenID razí opačnou filosofii – jedno heslo platí všude.

Je potřeba připustit, že to není s pravidlem „jiné heslo pro každý web“ v rozporu, protože ono jedno heslo se zadává jen u jednoho OpenID providera. Na druhou stranu, ztráta takového hesla má řadově větší dopad a s rozmachem OpenID se dá očekávat, že se útočníci na tyto hesla zaměří.

Sumárum: dovedu si představit budoucnost v OpenID, ale zatím každému webdeveloperovi radím, ať je na stránkách nepoužívá. Ale oni stejně nemají zájem. Třeba stran OpenID nepadl pod článkem o Přihlašování uživatelů v Nette ani jeden dotaz – a že jsem pár rýpavých očekával ;)

clock 26. 5. 2009 pencil PHP comments Komentáře: 15


Escapování - definitivní příručka

Největší programátorský evergreen jsou zmatky a nejasnosti kolem escapování. Neznalost způsobuje, že nejtriviálnější metody narušení webových stránek, jako třeba Cross Site Scripting (XSS) nebo SQL injection, patří mezi nejrozšířenější.

Escapování je převod znaků majících v daném kontextu speciální význam na jiné odpovídající sekvence.

Příklad: do řetězce ohraničeného uvozovkami chceme zapsat uvozovky. Jelikož uvozovky mají v kontextu řetězce speciální význam a jejich prosté zapsání by bylo chápáno jako ukončení řetězce, je potřeba je zapsat jinou odpovídající sekvencí. Jakou přesně určují pravidla kontextu.

Předpoklady

Každá escapovací funkce předpokládá, že vstupem je vždy surový řetězec v určitém kódování (znakové sadě).

Odbočka: PHP obsahuje historický relikt nazývaný magic quotes. Pokud jsou magic quotes aktivní, PHP při spuštění automaticky zavolá nad takřka všemi vstupními řetězci v superglobálních polích funkci addslashes, čímž je pozmění a znehodnotí pro další zpracování. Magic quotes vznikly na základě chybného předpokladu, nemají žádný pozitivní přínos, ba právě naopak. V novějších verzích PHP budou magic quotes odstraněny. Zatím je nutné je vypínat (např. požádat hostera o vypnutí) nebo povinně na začátku spouštěného skriptu zavolat tento kód, který způsobené modifikace zvrátí a budeme mít opět k dispozici vstup v surovém tvaru.

Mimochodem ze stejného důvodu je také kontraproduktivní třeba ukládat do databáze řetězce již předem escapované pro HTML výstup a podobně.

S jakými kontexty se setkáváme?

Jak bylo řečeno, escapování převádí znaky mající v určitém kontextu speciální význam. Pro každý kontext se používají jiné escapovací funkce. Tato tabulka je pouze orientační, je nutné si přečíst poznámky níže.

kontext escapovací funkce reverzní funkce
HTML htmlspecialchars html_entity_de­code
XML htmlspecialchars
regulární výraz preg_quote
PHP řetězce var_export
MySQL databáze mysql_real_es­cape_string
MySQL improved mysqli_real_es­cape_string
SQLite databáze sqlite_escape_string
PostgreSQL databáze pg_escape_string
PostgreSQL, typ bytea pg_escape_bytea pg_unescape_bytea
JavaScript, JSON json_encode json_decode
CSS addcslashes
URL rawurlencode urldecode

Vysvětlení k následujícím poznámkám:

  • řada kontextů má své podkontexty a v nich se escapování liší. Nebude-li řečeno jinak, je uvedená escapovací funkce použitelná plošně bez dalšího rozlišování podkontextů.
  • pod pojmem obvyklá znaková sada se rozumí znaková sada s 1bajtovým nebo UTF-8 kódováním

HTML

V HTML kontextech mají souhrnně speciální význam znaky < & " ' a odpovídající sekvence jsou &lt; &amp; &quot; &#039;. Výjimkou je HTML komentář, kde má speciální význam jen dvojice --. K escapování se používá:

htmlspecialchar­s($s, ENT_QUOTES)

Funguje s libovolnou obvyklou znakovou sadou, jiné je třeba konzultovat s manuálem. Ale pozor, tato funkce nezohledňuje podkontext HTML komentářů (tj. neumí nahradit dvojici -- za něco jiného).

Reverzní funkce může plnohodnotně fungovat pouze s UTF-8 (vyžaduje PHP 5):

html_entity_de­code($s, ENT_QUOTES, 'UTF-8')

XML / XHTML

XML 1.0 se od HTML liší v tom, že zakazuje použití kontrolních znaků C0 (a to včetně zápisu v podobě entity) s výjimkou tabulátoru, odřádkování a mezery. XML 1.1 tyto zakázané znaky s výjimkou NUL v podobě entit naopak povoluje a dále přikazuje kontrolní znaky C1 s výjimkou NEL taktéž zapisovat jako entity. Dále v XML má speciální význam sekvence ]]>, proto je třeba jeden z těchto znaků také escapovat.

Pro XML 1.0 a libovolnou obvyklou znakovou sadu tak lze použít (zdroj © Nette Framework):

htmlspecialchar­s(preg_replace('#[\x00-\x08\x0B\x0C\x0E-\x1F]+#', '', $s), ENT_QUOTES)

Regulární výraz

Perlových regulárních výrazech mají souhrnně speciální význam znaky . \ + * ? [ ^ ] $ ( ) { } = ! < > | : - a tzv. delimiter, což je znak ohraničující regulární výraz (např. pro výraz '#[a-z]+#i' je to #). Escapuje se znakem \.

preg_quote($s, $delimiter)

Kódování musí být buď 1bajtové nebo UTF-8, podle modifikátoru v regulárním výrazu. Viz také Escapování v regulárních výrazech.

PHP řetězce

PHP rozlišuje dva typy řetězců:

  • v jednoduchých uvozovkách a NOWDOC, kde speciální význam mohou mít znaky \ '
  • ve dvojitých uvozovkách a HEREDOC, kde speciální význam mohou mít znaky \ " $

Escapuje se znakem \. To obvykle provádí programátor při psaní kódu, pro generátory PHP kódu lze využít funkci var_export.

Poznámka: protože zmíněné regulární výrazy se obvykle zapisují uvnitř PHP řetězce, je potřeba zkombinovat obě escapování. Např. znak \ se pro regulární výraz zapíše jako \\ a v PHP souboru je třeba psát \\\\. Viz také Regulární korektura Intervalu.cz.

SQL a databáze

Každá databáze má svou vlastní escapovací funkci, viz tabulka výše. Téměř vždy je ale dostupná jen funkce pro escapování řetězců a tu nelze použít k ničemu jinému, zejména chybí funkce escapující zástupné znaky používané v konstrukcích LIKE (v MySQL jde o znaky % _) nebo identifikátory, jako jsou názvy tabulek či sloupců. Databáze nevyžadují odstraňování escapování na výstupu! (S výjimkou např. typu bytea.)

Znakové sady s neobvyklým vícebajtovým kódováním je nutné v MySQL nastavit funkcí mysql_set_charset resp. mysqli_set_char­set.

Doporučuji používat databázový layer (např. dibi, PDO) nebo parametrické dotazy, které escapování obstarají za vás.

JavaScript, JSON

Jakožto programovací jazyk má řadu velmi odlišných podkontextů. K escapování řetězců lze využít vedlejší efekt funkce

json_encode((strin­g) $s)

která navíc obalí řetězec do uvozovek. Striktně vyžaduje UTF-8.

JavaScript zapsaný uvnitř HTML atributů (např. onclick) je nutné ještě escapovat podle HTML pravidel, neplatí to však pro JavaScript uvnitř značek <script>, kde musí být ošetřen pouze případný výskyt koncové značky </script> uvnitř řetězce. To ovšem funkce json_encode zajistí, jelikož JSON escapuje lomítko /. Neošetří však konec HTML komentáře --> (což v HTML nevadí) nebo XML bloku CDATA ]]>, do kterého se skript obaluje. Pro XML/XHTML je řešením

str_replace(']]>', ']]\x3E', json_encode($s))

Jelikož JSON využívá podmnožinu syntaxe JavaScriptu, je reverzní funkce json_decode plně použitelná jen pro JSON, pro JavaScript omezeně.

CSS

V CSS kontextech je rozsah platných znaků přesně vymezen, pro escapování identifikátorů lze použít například tuto funkci (zdroj © Nette Framework):

addcslashes($s, "\x00..\x2C./:;<=>?@[\\]^`{|}~")

Pro CSS uvnitř HTML kódu platí totéž, co bylo řečeno o JavaScriptu a jeho escapování uvnitř HTML atributů a značek (zde se jedná o atributy style a značky <style>).

URL

V kontextu URL se escapuje vše kromě písmen anglické abecedy, číslic a znaků - _ . nahrazením za % + hexadecimálně vyjádřený bajt.

rawurlencode($s)

Podle RFC 2718 (z roku 1999) nebo RFC 3986 (z roku 2005) je preferován zápis znaků v kódování UTF-8 (zdaleka ne každý web to dodržuje).

Reverzní funkcí je v tomto případě urldecode, která rozeznává i znak + s významem mezery.


Všimněte si, že nebyl zmíněn žádný kontext, kde by se využily funkce addslashes nebo stripslashes – zapomeňte na ně!

Pokud se vám zdá celá problematika příliš složitá, nezoufejte. Brzy přijdete na to, že jde vlastně o jednoduché tranformace a celý trik spočívá v uvědomění, v jakém kontextu se nacházím a jakou musím pro něj zvolit funkci. Nebo ještě lépe, zkuste použít inteligentní šablonovací systém, který dokáže kontexty rozeznat sám a použít správné escapování: Nette\Template.

clock 19. 5. 2009 pencil PHP comments Komentáře: 11


phpFashion © 2004, 2010 David Grudlo webu

Pokud není uvedeno jinak, podléhá obsah těchto stránek licenci Creative Commons BY-NC-ND Creative Commons License BY-NC-ND

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.