Přejít k navigační liště

Zdroják » JavaScript » Co je Cross-site scripting jak mu předcházet

Co je Cross-site scripting jak mu předcházet

Články JavaScript, PHP, Různé

XSS neboli Cross-Site Scripting je jedna z nejstarších zranitelností webových aplikací. A protože jí stále mnoho webů, resp. webových aplikací trpí a většina uživatelů má JavaScript zapnutý, ukážeme si jednoduché příklady, jak zranitelnost vzniká a jak se jí bránit. Článek je věnován zejména těm, kdo o XSS zatím pořádně neslyšeli.

V tomto článku budeme vyžadovat alespoň základní znalosti HTML, CSS a JavaScriptu. Pro serverově orientované příklady byl zvolen značkovací jazyk PHP pro jeho jednoduchost a rozšířenost.

Na úvod: co mohou způsobit znaky „<“ a „>“

Začneme příkladem. Mějme jednoduchou stránku s jedním vstupním polem, které je součástí formuláře. Formulář odesílá svůj obsah na stejnou stránku a zobrazí obsah odeslaného políčka.

<html>
<body>
  <form>
    <input type="text" name="test">
    <input type="submit" value="Odeslat a zobrazit">
  <br>
<?php
if (isset($_GET['test'])) {
    echo 'Odeslaná hodnota je: ' . $_GET['test'];
}
?>
  </form>
</body>
</html> 

Co se stane, když do našeho formuláře zadáte slovo „pokus“? Na výsledné stránce se zobrazí slovo „pokus“. Co se ovšem stane, když k němu přidáte značky HTML a zadáte např. „<b>pokus</b>“? Zobrazí se tučně slovo „pokus“.

Jinými slovy – v tomto případě můžete libovolně měnit HTML stránku. Uvedený příklad je jedním z mnoha případů XSS. Kromě celkem neškodné značky pro tučné písmo můžete vložit i kód spouštějící JavaScript (odtud také pochází název Cross-Site Scripting). Podívejte se na několik ukázek možných vstupů a na jejich výsledky (možností je ale daleko víc):

uživatelský vstup akce v prohlížeči
<b>pokus</b> zobrazí se „pokus“ (tučně)
<img src=x onerror=„aler­t(‚XSS‘);“> vyskočí javascriptové okno s nápisem XSS
<img src=„http://h­acker.example­.cz“> zobrazí se obrázek z útočníkovy stránky

Jak se útoku bránit? V našem případě postačí, když nahradíme znaky „<“ a „>“ HTML entitami, tedy „&lt;“ a „&gt;“.

Pro začátek předvedeme tu nejjednodušší funkci, která je k dispozici snad v každém programovacím jazyce – nahrazování výskytu řetězce za jiný – v PHP je to str_replace. Uvedený kód tedy změníme na následující:

echo 'Odeslaná hodnota je: ' . str_replace(array('<', '>'), array('&lt;', '&gt;'), $_GET['test']); 

Tím jsem uvedený příklad ochránil proti XSS. Ale pozor, tato obrana není v některých případech dostačující. Proto čtěte dál.

Co může způsobit uvozovka nebo apostrof

Rozšíříme předchozí příklad – pro snadnou změnu během testování zobrazíme odeslanou hodnotu i v textovém poli.

<html>
<body>
  <form>
    <input type="text" name="test" value="<?php echo $_GET['test']; ?>">
    <input type="submit" value="Odeslat a zobrazit">
    <br>
<?php
if (isset($_GET['test'])) {
        echo 'Odeslaná hodnota je: ' . $_GET['test'];
}
?>
  </form>
</body>
</html> 

Po vyzkoušení uživatelských vstupů z první tabulky se může zdát, že je vše v pořádku. Ale to je omyl, viz následující vstupy:

uživatelský vstup akce v prohlížeči
„><img src=“http://h­acker.example­.cz/obrazek.jpg“><x x=“ zobrazí se obrázek z útočníkova serveru
“ onclick=„aler­t(‚XSS‘);“ x=“ vyskočí javascriptové okno po kliknutí do políčka

Kromě znaků „<“ a „>“ musíme totiž ošetřit i uvozovky („) a apostrofy (‚), podle toho, co používáme. V PHP se pro tento účel používá funkce htmlspecialchar­s().

<input type="text" name="test" value="<?php echo htmlspecialchars($_GET['test'], ENT_QUOTES); ?>"> 

Co v případě značky textarea?

V dalším příkladu předvedeme ještě jedno ošetření HTML, kde nemusí být na první pohled jasné, proč jej vůbec dělat. Na první pohled se totiž může zdát, že není nutné nic ošetřovat. Mějme následující příklad:

<html>
<body>
  <form>
    <textarea name="test"><?php echo $_GET['test']; ?></textarea>
    <input type="submit" value="Odeslat a zobrazit">
  </form>
</body>
</html> 

Pokud budete zkoušet prozatím uvedené uživatelské vstupy, značku textarea neprolomíte. Zkuste ale dodat do uživatelského vstupu její vlastní uzavírací značku.

uživatelský vstup akce v prohlížeči
</textarea><img src=„http://h­acker.example­.cz/obrazek.jpg“> zobrazí se obrázek z útočníkova serveru

A obrana? Jako v prvním příkladu – převádět znaky „<“ a „>“ na jejich HTML entity, například pomocí funkce htmlspecialchar­s().

Obrana v samotném JavaScriptu

Výše uvedené příklady měly jedno společné – uživatelský vstup se ošetřoval na straně serveru. A co když nás serverová strana zrovna nezajímá, můžeme si nezabezpečená data ošetřit i na klientské straně? Ano, i to jde, ukážeme si další příklad:

<html>
<body>
  <script>
    function zobraz() {
      document.getElementById('vysledek').innerHTML =
           'Odeslaná hodnota je: ' +
           document.getElementById('test').value;
      }
  </script>

  <input type="text" id="test">
  <input type="submit" onclick="zobraz();" value="Zobrazit">
  <br>
  <div id="vysledek"></div>
</body>
</html> 

V příkladu je použita metoda innerHTML(), ta umožňuje upravit (resp. nahradit) část HTML dokumentu. Vyzkoušejme následující vstupy:

uživatelský vstup akce v prohlížeči
pokus zobrazí se „pokus“
<b>pokus</b> zobrazí se „pokus“ (tučně)
<img src=„http://h­acker.example­.cz“> zobrazí se obrázek z útočníkova serveru
<b onmouseover=„a­lert(‚XSS‘);“>n­ajeď myší přes tento text</b> vyskočí javascriptové okno s nápisem XSS

Obrana je stejná jako u prvního příkladu: nahradíme nebezpečné znaky jejich HTML entitami. V JavaScriptu použijeme metodu replace().

function zobraz() {
document.getElementById('vysledek').innerHTML =
       'Odeslaná hodnota je: ' +
       document.getElementById('test').value.replace(/</g, '&lt;').replace(/>/g, '&gt;');
} 

Míchanice: HTML + PHP + JavaScript

PHP svou jednoduchostí přímo svádí k míchání kódu (např. v samotném HTML použijeme pro výpis hodnot PHP), a tak snad nepřekvapí ani generování JavaScriptu z PHP. Může se někdy samozřejmě hodit, ale opět je nutné si dát pozor.

<html>
<body>
<script>
  window.onload = function() {
    var value = 'Odeslaná hodnota je: <?php echo $_GET['test']; ?>';
    value = value.replace(/</g, '&lt;').replace(/>/g, '&gt;');
    document.getElementById('vysledek').innerHTML = value;
  }
</script>

  <form>
    <input type="text" name="test">
    <input type="submit" value="Odeslat">
    <div id="vysledek"></div>
  </form>
</body>
</html> 

Zobrazení hodnoty je zde již ošetřeno. Ale podle předchozích zkušeností s uvozovkami a apostrofy nás hned napadne, jak apostrof prolomit.

uživatelský vstup akce v prohlížeči
‚; alert(„XSS“); value = ‚není tu nic vyskočí javascriptové okno s nápisem XSS

Pokusíme se tedy ošetřit apostrofy a uvozovky, ale pozor, to není celá obrana. Existuje totiž další možnost, jak JavaScript ukončit. Je to značka pro ukončení skriptu: „</script>“ nebo i její kratší varianta „</script “ (mezera či jakýkoliv jiný prázdný znak na konci). Jakmile interpret JavaScriptu narazí na tento výskyt znaků, ukončí se javascript a dále se pokračuje ve zpracování HTML.

uživatelský vstup akce v prohlížeči
</script><scrip­t>alert(„XSS“)</sc­ript> vyskočí javascriptové okno s nápisem XSS
</script><img src=„http://h­acker.example­.cz“> zobrazí se obrázek z útočníkovy stránky

A jak se bránit v tomto případě? Nejjednodušší je opět nahradit „nebezpečné znaky“: < a > za jejich HTML entity.

Další případ: uživatelským vstupem je HTML

Výše uvedené příklady pracovaly jen s prostým textem a cílem bylo jej zobrazit. Existují situace, kdy uživatelským vstupem skutečně je HTML, typickým případem může být webové rozhraní e-mailu. Zde vyvstává řada dalších otázek:

  • Co s nevalidním HTML?
  • Budou se zobrazovat externí obrázky?
  • Povolíme kaskádové styly?
  • Co s JavaScriptem?
  • Co s formuláři?
  • … (a řada dalších)

Na jednu stranu chceme zajistit bezpečnost a na druhou stranu uživatel chce mít „hezky vypadající e-mail“ – prostě HTML. Existuje více způsobů, jak řešit tento problém, ale nejúčinnějším řešením je použití tzv. whitelistu – seznamu HTML značek a jejich atributů, jejichž vložení povolíme (protože jsou bezpečné). Příklad takového velmi krátkého whitelistu:

povolená značka povolený atribut
p
a href
b

Odpovíme na předchozí otázky s pomocí této tabulky:

  • Co s nevalidním HTML?
    Nevalidní HTML budeme muset nejdříve převést na validní HTML (pokud je tedy nechceme rovnou zahodit). Prohlížeče to také řeší (a bohužel každý trochu jinak), ideálně k tomu použijeme nějakou hotovou knihovnu.
  • Budou se zobrazovat externí obrázky?
    Ne, značka „img“ není v našem whitelistu povolena.
  • Povolíme kaskádové styly?
    Ne, značka „link“ pro načtení externího stylopisu není povolena, ani atribut „style“ není povolen.
  • Co s JavaScriptem?
    Odfiltruje se. Značka „script“ není povolena ani žádné atributy využitelné jako ovladače událostí nejsou povoleny (příkladem může být „onclick“) ani kaskádové styly nejsou povoleny (i ty by mohly vést ke spuštění JavaScriptu, viz níže). Nesmíme ovšem zapomenout zkontrolovat i obsah povoleného atributu href (ten by mohl obsahovat javascriptový kód uvozený prefixem „javascript:“)
  • Co s formuláři?
    Odfiltrují se. Značky „form“, „input“ ani další formulářové značky nejsou povoleny.

Z košatého HTML na vstupu se zahodí veškeré nepovolené HTML značky a atributy. Zůstanou jen ty povolené.

XSS a kaskádové styly

Kaskádové styly úzce souvisí s předchozí problematikou zobrazování uživatelského HTML. I zde existují možnosti, jak útočit a např. spustit JavaScript. Příkladem může být vlastnost expression dostupná v Internet Exploreru:

<div style="width: expression(alert('XSS'));"> 

Pro Firefox (a všechny prohlížeče postavené na jádru Gecko) existuje v kaskádových stylech také vlastnost, která umožňuje spuštění JavaScriptu (podrobnosti najdete v XSS Cheat Sheet), viz příklad:

<p style=-moz-binding:url(xssByCssInFirefox.xml#xss);>text</p> 

Řešení? Podobně jako v předchozím příkladu: whitelist, čili povolit jen ty vlastnosti, které opravdu povolit chceme.

Napsat vlastní HTML/CSS filtr není nic jednoduchého, proto pravděpodobně použijete nějakou hotovou knihovnu, v případě PHP např. projekt HTML Purifier.

Závěr

Tvůrci webů a webových aplikací by měli myslet na bezpečnost a nezapomínat pečlivě ošetřovat veškeré vstupy od uživatelů. Veškeré možné útoky včetně jejich podpory v nejpoužívanějších prohlížečích se dají nastudovat na XSS Cheat Sheet od RSnake.

Uživatelé Firefoxu se pak mohou chránit proti mnoha typům XSS pomocí rozšíření NoScript. Má však zpočátku otravnou, ale jinak velmi účinnou, vlastnost. Musíte NoScript nejdříve naučit, jaké weby mohou používat JavaScript ve vašem prohlížeči.

Odkazy


Autorem článku je Jan Pejša, vývojář webových aplikací ve společnosti Kerio Technologies s.r.o., která je jedním z hlavních výrobců bezpečnostního internetového softwaru pro malé a středně rozsáhlé sítě, se specializací na síťové firewally a bezpečnost interní firemní komunikace.

Komentáře

Subscribe
Upozornit na
guest
54 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
danaketh

Zrovna GET řeším tím, že z něj odstraním vše, o čem vím že nemůže nikdy obsahovat. Třeba v případě odkazu na článek vím, že nebude nikdy obsahovat špičaté závorky, apostrofy, uvozovky, lomítka, středníky… takže je v klidu smažu.

Stejně tak by se mělo vždycky provádět ošetření na straně serveru, protože JavaScript lze snadno potlačit (no, zrovna tím NoScriptem). Ideálně všechno posílat přes POST a GET používat jen tam, kde přesně víme co z něj může přijít.

Keson

Obecně lepší přístup, než odstraňovat určité špatné znaky, je akceptovat pouze povolené.
Na straně klienta se data kontrolovat mohou, na straně serveru musí. Jinak se nedá o bezpečnosti vůbec mluvit.
Z hlediska bezpečnosti (korektnosti vstupu) je úplně jedno, jestli použijete POST, GET, nebo jinou metodu. GET má zřejmou (ne)výhodu, že se dá zazáložkovat.

benzin

Ano, pri pouzivani GET je URL adresa vzdy odpovidajici obsahu stranky a tak to ma na webu byt.

dan

Autor asi nikdy neslysel o htmlspecialchars()… a ze by se to melo volat minimalne kvuli spravnemu zapisovani < > " a & do html pri kazdem vypisu

xmorave2

komentátor asi nečetl článek…

dan

Cetl a proto me zarazi ze autor nedokaze jednoduse napsat ze VSE CO SE VYPISUJE musi jit pres htmlspecialchars() *. A v pripade ze to je jeste hodnota do JS, tak napr. addslashes(), ktera vyresi ' a .

Namisto toho resi ruzne replace blbosti jako ten nejvetsi amater co nahodou zjistil ze to mensitko a vetsitko bude asi nebezpecne a to jen diky tomu ze mu nejaka dalsi osoba ukazala specialni odkaz jak exploitnout jeho stranky. Takze se snazi resit JEDEN konkretni pripad, ne problem jako celek, ze pise kod jako prase.

Bohuzel se s timto pristupem setkavam casto a namisto SLUSNEHO programovani ti pisalci resi ruznymi obezlickami konkretni problemy az nastanou. A uplne to same plati o SQL injection a taky o shellu, v pripade PHP je hruzny priklad i v komentarich zde http://cz.php.net/manual/en/function.rmdir.php :

function removeDir( $dir ) {
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
exec( "rd /s $dir" );
} else {
exec( "rm -rf $dir" )
}
}

Proc tam sakra neni escapeshellarg() ? Vsak az to nekomu smaze server tak ho tam priste da.. mozna, ze?

Pak to skonci bohuzel s tim ze 95% autoru budou psat jak prasata a musi se zavest az takove zmeny jako magic-quotes-gpc aby se neposkodila povest programovaciho jazyka samotneho. Nastesti to je uz deprecated feature.. portovatelny kod ale s tim musi pocitat a jakykoliv zdrojak ktery obsahuje

echo $_GET['promenna']

me rika ze autor si problematiky neni znam. A pokud se to objevi v clanku o bezpecnosti, bezpecnosti PHP, tak je to k smichu. Pokud je magic-quotes-gpc defaultne ON, tak na tento kod z clanku:

'Odeslaná hodnota je: <?php echo $_GET['test']; ?>';

exploit z clanku:

'; alert("XSS"); value = 'není tu nic

fungovat nebude. magic-quotes-gpc mu ty apostrofy zmeni na ' jeste pred spustenim skriptu. Ale nikde zminka o tom ze by pan pouzival super nove php nebo nejake s upravenou (nedefaultni) konfiguraci neni.

A to jeste ke vsemu dela na takove pozici, ach jo.

*) Nemusi kdyz to je primo vysledek (interni) funkce vracejici cislo nebo pretypovani. Jinak ten kod muze byt explotnutelny kdyz se zmeni format vystupu uzivatelske funkce.

Hoween

Chcete kvalitní články? Nečtěte Zdroják. Bastličů, kteří píší články a armáda jiných bastličů jim v komentářích děkuje, tady bohužel přibývá. A když se člověk proti článku ohradí, tak se na něj všichni, často včetně šéfredaktora, sesypou.

Ale je nutné na to upozornit a absolutně s vámi souhlasím. Bezpečnost aplikace začíná od jejího celkového návrhu, nikoli dolepováním patchů řešících konkrétní problémy. Vezměte si analogii Win vs. Linux. Zatímco Linux má bezpečnost řešenou od začátku, a je s ním mnohem méně problémů, u Win se na bezpečnost kašle a lepí se konkrétní chyby, které někdo najde. Že je správně ten první případ, víme oba. Proč to neví redaktoři a tohle pustí ven, je věc druhá.

Miroslav Juhos

Zřejmě se na vás všichni sesypou kvůli onomu výstřednímu způsobu jakým svoje názory podáváte.

Koneckonců, budete-li chtít přispět článkem, který bude demonstrovat vaše představy o kvalitě článků na Zdrojáku a který nastaví laťku i ostatním článkům, dá se předpokládat, že pan šéfredaktor se bránit nebude.

SFS

Jak ma podle vas Linux resenou bezpecnost v porovnani s Windows, aby bylo mozno napsat, ze je by-design imunni vuci programatorskym chybam napr. v kernelu ?

Hoween

Linux má bezpečnost řešenou tak, že za celou dobu jeho existence na něj vzniklo cca 30 virů. Windows mají bezpečnost řešenou tak, že na ně existuje virů víc než 200 tisíc.

Co do toho pletete nějaký by-design a kernel? Jde o koncepci návrhu.

SFS

Zkuste BeOS – pro nej nejsou viry vubec zadne ;-) Nejde o kvantitu – tech 200 tisic viru pro Windows opakovane vyuziva stejne techniky (az na par objevnych vyjimek). Takze zranitelnost vedouci k napsani byt jedineho viru (a vy jich zminujete pro Linux hned tricet ;-) muze snadno vyustit v ty tisice, pokud to bude pro danou platformu zajimave vyvijet.

dan

Odpoved konkretne na vasi otazku je "protoze je opensource" :)

Ale autor prispevku vyse mel na mysli to:

– ze linux nikdy nemel nechraneny rezim
(jako win az po ME)

– ze linux neposkytuje roota pro beznou praci usera po instalaci
(zatimco ve win ma uzivatel nejdrive admin prava, kterych se musi aktivne zbavit)

– ze linux vzdy pouzival pristupova prava (minimalne rwx), a ACL snad umi vsechny FS
(zatimco ve win casto mate fat, fat32, … vse bez pristupovych prav)

– linux je napsan portovatelne a jeho ruzne varianty (i v ramci jedne architektury – staci prekompilovat s jinou urovni optimalizace) zpusobuji ze vyuzit nejaky remote/local buffer overflow je o nekolik radu tezsi.
(naproti tomu ve windows mate jednu a tu samou binarku pro kazdeho.. to se pak exploituje ;)

A urcite se najde spousta dalsich vlastnosti PROC tomu tak je.

Rekl bych ze existuji stastni uzivatele Linuxu a nestastni Windowsaci co nam to zavidi a vyvolavaji flamewar :)

PS. Windows je lepsi – ale bohuzel jen marketingove/obchodne. Co se tyce technickych kvalit, tak tam opravdu zaostava. A to jsou dva nesrovnatelne aspekty, takze to prosim neplest.

SFS

– Mluvme o systemu nad NT architekturou a nikoliv win9x.
– NTFS je jako nativni uz od prvnich verzi a nabizi vse, co potrebujete.
– Zkuste si nekdy nainstalovat XP – budete prekvapen, ze hned pri instalaci vytvorite krome roota i non-privileged uzivatele a pod nim vam take system nabidne defaultne se prihlasit. Ze se pak kazdy hlasi pod adminem je vec jina – problem se spatne napsanymi aplikacemi je bohuzel dost rozdireny – ale v Linuxu je to nanestesti casto totez – napr. KINO z distribuce Mandrivy 2009.0 se odmitne dohodnout s DV kamerou pres 1394 – ze nelze otevrit /dev/raw1394 – proc ? Zarizeni nefunuje/nejde nainicializovat, jiny problem ? Zoufaly uzivatel po hodine badani zjisti, ze autor aplikace jaksi zapomel osetrit access denied k /dev/raw1394, aplikace reaguje hlaskou "unable to open..", takze sudo chmod vec resi ;-)

Btw pouzivam Windows (ktere znam, troufam si rici, lepe nez lecktery vyvojar od Microsoftu), pouzivam Linux pro cross-platform development (stejne jako MacOSX) a nevidim nejaky zasadni rozdil (minimalne v navrhu systemu – a ten byl v puvodnim prispevku zminovan).

dan

– existovali i jina win, nez se nezjistilo ze nejsou pouzitelna v moderni sitove dobe. Ale pokud zacneme u NT.. myslite ty NT, kde mel administrator prazdne heslo ? :) (win2000). Nj, byla to srandovni doba kdyz jsme museli userum na kolejni siti vysvetlovat ze to heslo tam je fakt potreba.

– existoval i FAT.. a nebyt tech velkych disku a omezujiciho limitu 4G na soubor tak se zrejme porad pouziva. Pozadavek na NTFS totiz Windows pro svuj beh nemaji, porad tvrdite ze je to tak spravne? Proc si myslite ze XP na ntfs ty prava vyuzivaji pokud xpckam na FAT32 evidentne neschazi?.

– ano o tom mluvim: ucet vytvoreny pruvodcem pri/po instalaci ma doopravdy administratorska prava, lisi se jen nazvem/loginem a tim ze se objevi na welcome obrazovce (nevim proc si mylne myslite ze ty prava nemaji – zdani klame)

– ohledne /dev/raw1394: je to problem distribuce a nastaveni udev rules a skupinovych prav. Resil jsem podobny problem s jinym hotplug hw – stacilo nahlasit a oprava byla na svete: http://bugs.gentoo.org/208578 . Kde lze podobne precizne nastavit prava ve windowsech k zarizenim? Bud je maji vsichni anebo je ma jen root a pak uzivatele pouzivaji admin ucet

– v navrhu systemu rozdil neni? Defaultni nastaveni nepatri do navrhu?

n0

k tomu heslu: jak to souvisí s debatou kolem návrhu win/nix?

A k tomu FATku bych dodal, že existují stanice, které nejsou připojeny k netu (a nemají USB) :)) a jsou používány jen jedním uživatelem, zato inteligentním? Potřebuje NTFS když si na tom bude přehrávat mp3jky < jak 4GB? :]

BTW ty trosky tam dostane přes CD-ROM ;p

blek džek

Godwinův zákon: Pravděpodobnost, že v diskusi na Rootu se téma stočí k boji Linux vs. Windows, se s růstem délky diskuse blíží jedničce.
:-))

Anonymní

se s rustem delky diskuse blizi klidne i dvojce :-)

Anonymní

takze sudo chmod vec resi ;-)

ne neresi
1. mandriva nepouziva sudo
2. chmod neresi (respektive vyresi to na chvili)
3. na chvili dokud se nespusti msec, ktery to vrati dle svych zaznamu zpet.

takze chmod + rekonfigurace prislusneho zaznamu v msec configu :-D

4. a to je duvod mimo jine take divod proc se blbe pisi viry a podobna havet pro linux.

na nic se tam nemuzete spolehnout klidne i v kernelu to muze byt vsecko jinak :-)

treba bsd kernel + debian gnu + LFS apps – to ze to snad nikdo nevidel neznamena ze to nekdo neprovozuje :-)

Anonymní

Jenže vy se na to díváte ze špatného pohledu – to, co jste napsal, platí bezezbytku pro autory dejme tomu multiplatformního konfiguračního softwaru, kteří to, že jim to nechodí na třetině počítačů, musí řešit jako problém. Autora virů tohle ale naprosto nezajímá, on má 66 % počítačů, které nakazit může, což je pro něj dobrá zpráva. Navíc si myslím, že pokud by jednou Linux měl nějaký významnější podíl, bude to spíš tak, že jedna distribuce bude mít 30 % a druhá 20, než že sto distribucí bude mít procento (kdy by se dalo mluvit o diverzitě).

czexit
Kuchař

Nevím proč, ale připomínáte mi toho kuchaře co teď běží na Primě, jak všechny vždycky pěkně zjebe :-)

yossarian

magic-quotes-gpc je vec, kterou nikdy v php nemeli implementovat.

Hoween

Jistě. Naservírujeme začátečníkovi XY způsobů jak patchnout to či ono, když nemá žádný teoretický základ a naučíme ho tak prasit své aplikace (jak je tomu u většiny PHP programátorů zvykem). První věc, kterou měl váš článek, nebo nedejbože seriál článků začít, je právě to, že popíšete konfiguraci PHP a jak které volby mohou ovlivňovat zabezpečení. To, že vy považujete magic_quotes za vypnuté (ano, já si je také nechávám všude vypnout), ještě neznamená, že na ostatních hostinzích jsou také vypnuté.

noaco

No a co? To je takovej problém používat get_magic_quotes_gpc()?

Hoween

Pro mě to problém není, pro autora to zřejmě problém je.

Znovu opakuji, že celému článku měl předcházet popis konfiguračních možností PHP, které takové věci mohou ovlivňovat.

Martin

O čem je článek? O PHP nebo o XSS? PHP byl zvolen jako demonstrační jazyk. Mě zaujalo, jaké jsou techniky XSS, ne jak se v PHP řeší. Autorovi + Vám -!

Hoween

Článek je evidentně o XSS v PHP. Kdyby nebylo zvoleno PHP jako nástroj, a řešilo se čistě XSS, neřekl bych půl slova. Ale takhle je to XSS včetně PHP, a to PHP je tam hodně, hodně špatné.

To sem vážně chodí samé nuly, co nad každým článkem slintají blahem a nevidí ty hromady chyb?

jar

Často je na hostingu starší verze PHP, často nemáme vliv na to, jestli magic je nebo není, takže:

<?php
function gpc_addslashes($str) { return (get_magic_quotes_gpc() ? $str : addslashes($str)); }>
?>

Zdroj: http://php.vrana.cz/obrana-proti-sql-injection.php

K escapování šířenji: http://php.vrana.cz/escapovani.php

http://php.vrana.cz/ vůbec celkově stojí za pečlivou pozornost.

Jinak za článek díky. Jako upozornění na problém je rozhodně přínosný.

Hoween

Nic proti, ale argumenty typu "často je …".
Vždycky mám možnost volby, a vždycky mám možnost se s hostingem dohodnout. Pokud je web na staré verzi PHP, domluvím si migraci na něco novějšího. Pokud je nevyhovující konfigurace, domluvím si její změnu (nebo to rovnou přes .htaccess udělám sám). Pokud mi hostér z nějakého důvodu nechce vyhovět, jdu jinam. Vždycky zvažuju, jestli mám nevhodnou konfiguraci webhostera obcházet podobnými obezličkami, nebo jestli je jednodušší se zařídit jinak. Když mě totiž situace dotlačí do jedné obezličky, můžu jich za chvíli mít celou knihovnu. Jen proto, že někdo má špatně nastavené PHP.

Ad. přínosnost článku – Vy jste doteď o XSS, HTML injection apod. nevěděl? A to vážně programujete?

Ped

Ale to neni clanek o tom jak zabranit XSS v PHP, je to obecne o principech XSS utoku a o tom jak se jim branit. V PHP existuje prijemna funkce htmlspecialchars, ale v jinem jazyku jeho ekvivalent byt nemusi a pak muze ke slovu prijit i str_replace.
To same plati o magic-quotes-gpc, nema vyznam to resit v clanku kde o PHP ani poradne nejde, a je tam ciste jen pro ilustraci.

Ze to podle toho nejaky lepic kodu naboucha do sve "aplikace" a bude si myslet jak na XSS vyzral je jiny problem, ale proti tomu obrany neni, lepici kodu se v prvni rade nikdy k "programovani" nemeli dostat.

Hoween

Bohužel, podobné články jim v tom lepení hodně zvyšují sebevědomí.

Chybí jakákoli výuka teorie, všichni hned "programují" a pak je to hodně vidět.

David Grudl

Pro escapování JavaScriptových řetězců nelze použít addSlashes(). Autor to tedy NEnapsal dobře.

Je potřeba použít něco takového http://code.google.com/p/nette/source/browse/trunk/Nette/compatibility.php#50

(trošku pokory, když sám 'plácáš blbosti')

Martin Hassman
David Grudl

Popis escapování pro JavaScript obsahuje faktickou chybu. Naprosto stačí ochránit uvozovky, není potřeba, přesněji řečeno je kontraproduktivní, nahrazovat znaky < a >. Dále by mělo být zmíněno, že k ochraně uvozovek se používá jiný postup, než je používaný ve zbytku článku (tj. nenahrazuje se za entity, ale přidává se lomítko). Nejlépe asi použít json_encode(), s tím, že tato funkce sama vloží uvozovky, tj. uvozovky pak nebudou součástí JavaScriptové šablony.

David Grudl

Tam naprosto stačí nahradit / za /.

Rozšíření "řádné" není, co třeba </script><script>alert("XSS")</script>

David Grudl

Redakční systém mi trošku upravil obsah, mělo tam být </ SCRipt> …

Jakub Vrána

Nikoliv, je to ten stejný řetězec. JavaScript totiž znaky za kromě vyjmenovaných výjimek interpretuje jako ten samý znak.

A formálně vzato je blok JavaScriptu ukončen posloupností </, takže kdyby se nepoužilo zpětné lomítko, bylo by lepší nahradit všechny '</' za '<' + '/'.

David Grudl

Ještě mě upozornil Jakub Vrána, což jsem úplně přehlédl, neb takový bug bych nečekal, v článku chybí ošetření znaku &, namísto zbytečného ošetřování >

Hoween

Konečně někdo přišel na to, co tvrdím od začátku? Že je ten článek k ničemu? Chcete mi tvrdit, že kdyby na to nikdo nepřišel, tak tam tu chybu prostě necháte ostatním čtenářům.

Nu vot, eto novinařina.

David Grudl

No … asi jo.

Jakub Vrána

Chyba není v tom, že dva různé vstupy vrátí stejný výstup. Chyba spočívá v tom, že se uživateli zobrazí něco jiného než zadal.

E-mailem jsem reagoval pouze na implementaci funkce zobraz (nezmiňoval jsi ji, ale já jsem se o ní včera bavil s Davidem Grudlem, tak jsem tak nějak předpokládal, že jsi na konverzaci navázal). Při samotném výpisu do HTML se za určitých okolností může jednat i o bezpečnostní chybu – vznikne totiž nevalidní dokument, takže pokud se pošle s typem application/xhtml+xml, tak se např. ve Firefoxu a Opeře vůbec nezobrazí. Tvůj článek sice pracuje s HTML, ale vzhledem k rozšířenosti XHTML by na to měl pamatovat.

Standa

Tady se jasně ukazuje, jak je programování webových aplikací na pytel. Místo abych se soustředil na problém, řeším jak odescapovat vstupy v javascriptu.

Hoween

Programování webových aplikací není na pytel. Na pytel je, že dneska všichni rovnou "programují" a lepí, místo aby začali od nějakého návrhu a teorie.

karf

Ošetřovaní vstupů a výstupů snad není specifikem webových aplikací :)

Ash

Jak bastlit pseudoochranu uživatelských vstupů. Chápu že to je pro začátečníky, ale nebylo by lepší jasně oddělit demonstrační část "toto lidé dělají a takto to může dopadnout", a část kde se ukáže jak se to dělá pořádně? Nějak se to smíchalo a sice začátečníkovi ukážete, v čem může být problém, ale už ne to, jak tomu jednoduše předcházet :(

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.