[ Webhosting profitux.cz ]
v6ak [ programování, bezpečnost, web, php, java, ... ] (Vít Šesták)
Buzz - v6ak Twitter - v6ak

štítky

Musí být na http vstupu jen string?

Máte-li GET/POST/COOKIE vstup, jste si jisti, že tam bude string, pokud tam něco bude? Nemusí tomu tak být! Může tam být například pole. A to může vést k různému nepředvídanému chování.

Píšu o tom, protože jde o často opomíjený problém.

Celý článek je zde.

diskuze

web
mail
comment
  1. Jakub Vrána

    Článek jde podle mě zbytečně do šířky. Tváří se, že popisuje problém u všech skriptovacích jazyků, přitom popisuje hlavně PHP a jednu ukázku v ASP.NET. Popis problému v JavaScriptu je ryze teoretický, "použitá platforma umožňující takto předat pole" ani není uvedena.

    K PHP:

    1. Stejně se chová i u cookies, autor mohl vynaložit minimum úsilí a prověřit to.

    2. V PHP lze takto předat skutečně jen pole nebo řetězec.

    3. Problém s kódováním by mohl nastat v případě, že by výchozí kódování bylo UTF-7 a skript to měnil třeba na UTF-8. Je to sice těžko očekávatelná kombinace, ale pořád lepší příklad než skript, který po Location vypisuje neošetřený výstup... (Chyba v tomto případě spočívá v tom, že se vypisuje neošetřený výsup, nikoliv v tom, že se neodeslala hlavička.)

    Moje doporučení je jiné: Nevypisovat na ostrém serveru do stránky žádné chyby. Toto doporučení platí obecně, nejen pro tento problém. Potom jsou důsledky tohoto problému minimální až žádné a není potřeba si skript zamořovat řadou testů, jestli mi skutečně přišel řetězec. Tento test je nutné dělat jen v případě, kdy by mi pole poškodilo data, což např. při ukládání dat do databáze nehrozí (předání jmeno[]= má stejný dopad jako předání jmeno=Array).

    23.1.2008 10:57:38
    17
  2. v6ak

    Předně se pokusím odhalit můj přístup k zabezpečení. Bezpečnost je koneckonců moje oblíbené téma.

    Snažím se myslet maximálně na budoucnost. Nebojuji s důsledky, ale s příčinou. I kdybych věděl, že něco na vstupu by teď zrovna nemělo vadit, budu se snažit, abych na to musel při dalších úpravách myslet minimálně. A jakékoli "neumím zneužít" si zásadně nepřekládám jako "nelze zneužít". I proto mám rád whitelist.

    Vím, že se problém netýká pouze php, tak jsem se ho snažil popsat obecněji, takže jde trošku více do šířky. V některých článcích mě totiž vadilo, že jsou specializované na php, přitom by se daly použít obecně. Proto ten záběr do šířky.

    K JavaScriptu: Chtěl jsem především ukázat trošku konkrétnější zneužití a ne jen teoretizovat. Do serverového JS bych osobně asi nikdy nešel a v platformách pro serverový JS se moc neorientuji, slyšel jsem něco o SSJS od Netscape a nějakém pokusu s Geckem. Ale nepovažoval bych to za úplně teoretický problém. Mohl bych místo toho psát něco o emulaci Javového varargs v php a omezení počtu akcí za den, ale ten polymorfismus je IMHO stravitelnější.

    K 1. (cookies): Jo, ale to snad není tak důležité. Důležitý je hlavně princip.

    K 2.: Je to možné. Ale i tak rád myslím do budoucna. Co když bude třeba php6 umět předat i objekt? Pravda, byla by to nekompatibilita. Ani první a asi ani poslední...

    K 3. (problém s kódováním): Ano, v HTML si nedovedu nic jiného představit než něco jako utf-8 vs. utf-7 (rozdílná bitrate). Jeden jiný trik s kódováním, o kterém uvažuji, si v HTML neumím představit. Možná by však mohl jet v JS. Vyžaduje VBR znakovou sadu. Zakládá se na sřetězení a "sežrání" znaku. Někdy to možná vyzkouším.

    K 3. (Location): To mě jen napadlo, tak jsem to napsal. Však jsem psal, že by to nebylo zrovna čisté. Ale znamenalo by to IMHO rovnou dvě chyby.

    K neposílání chyb: Mám jedno takové přirovnání: Taky mám doma antivir. Správně by neměl být vůbec potřeba (zanedbám některé ostatní uživatele, kteří však mají malá práva), ale co když ostatní ochrany (jako oprávnění, záplatování a firewall) selžou? Nespolehl bych se však jen na pouhý antivir. Ten jen řeší problém, který správně neměl nastat.

    Jinak řečeno, taky doporučuji vypnout chybová hlášení, ale je to boj s důsledky, ne s prvotní příčinou. Navíc chybová hláška nemusí být jediný možný důsledek.

    Ano, při použití některých DB API může být výsledek stejný jako při vstupu jmeno=Array, ale jak jsem říkal, je jednodušší prostě ke kontrolám isset/array_key_exists přidat kontrolu is_string, než při každé změně myslet na to, jaké kontroly budu muset přidat. Navíc je vhodné použít nějakou formulářovou knihovnu (Zend_Form, Ronnie_Form, NForm, já používám vlastní třídy), která by měla vše (isset/array_key_exist i is_*) kontrolovat. Pak je to sranda.

    Jako maximální ústupek jsem výjimečné ochoten udělat něco jako @(int)$_GET['id']. Zde zabraňuji zobrazování chybových hlášek jen na konkrétním místě a nedělá to takové problémy, jako celkové vypnutí.

    Nakonec se přiznám, že sice v ostrém provozu taky doporučuji display_errors=off a vypisovat obecné chybové hlášky ("nastala chyba" místo "chyba při spojení s DB"), v praxi však dodržuji jen to druhé. Připravuji řešení, abych mohl mít doma například jiný .htaccess než na serveru, ale ještě není hotové. A vypnout si chybové hlášky doma by byla IMHO blbost. Správný skript by se IMHO neměl nechat "vyprovokovat" od nějakého vstupu v vypsání jakékoli chybové hlášky, včetně E_STRICT.

    24.1.2008 9:25:15
    18
  3. v6ak

    <OT> Koukám, že se mi CSS u tlačítka "reagovat na komentář" trošku nepovedl... ToDO. </OT>

    24.1.2008 9:27:28
    19
  4. Jakub Vrána

    [1] Předně abychom si rozuměli - kritizuji hlavně formu, nikoliv obsah článku. Do odborného článku si nemůžeš dovolit napsat "tohle jsem nezkoušel" nebo "takhle nějak podobně to asi bude fungovat i jinde".

    K těm chybám - zobrazování chyb by na ostrém serveru mělo být vypnuté přímo v php.ini. Ono i při vypnutém zobrazování chyb s nimi musíš nějak naložit - nejlépe je ukládat do logu a ten si po večerech číst. Ale menší zlo je podle mě mít v logu uložené pokusy o útok (to se může hodit i pro analýzu útočníkova chování a odhad možných důsledků), než mít skript zaplevelený spoustou kontrol, které se samotnou myšlenkou kódu nijak nesouvisí.

    Operátor @ bych v tomto případě rozhodně nepoužíval a nechal jeho použití pouze pro případ, kdy možnou chybu ošetřuji přímo v kódu sám.

    24.1.2008 9:49:24
    20
  5. v6ak

    (Celé je to odpověď na [4])

    Dobře ty cookies jsem dopsal.

    K "takhle nějak podobně to asi bude fungovat i jinde": taky jsem to trošku upravil. Problém je, že nemůžu mluvit konkrétně, protože jsem to pojal trošku víc do šířky, ani obecně, protože nikde není psáno, že se tak každá platforma musí chovat. A i kdyby se tak každá platforma chovala a já to měl ověřený, neměl bych zaručeno, že žádná taková platforma nevznikne. Takže jsem to vyřešil kompromisem.

    Obě změny jsem vyznačil tagy del a ins.

    K chybám: mluvím-li o freehostingu, pak o php.ini nemá smyls mluvit, je potřeba použít .htaccess. A s logy je to většinou stejný. Direktiva error_reporting je většinou natavena na (E_ALL & ~E_NOTICE) & ~E_STRICT (píšu to i pro budoucí verze php, kkde E_STRICT bude v E_ALL) a hnout s tím lze jen přes .htaccess, kde zatím mám výše uvedený problém.

    Co se týče logování chyb, tak v případě výjimek to řeším přes mail, což je v kombinaci s SMS e-mailem skvělá věc. V případě E_* píšu skripty tak, aby nenastaly. Nedávno jsem psal konvertor E_* na výjimky. Takže je to jen otázka času.

    Ke kontrolám: já radši k isset/array_key_exists přidám is_string, než abych při každé změně přemýšlel, co mi to ovlivní a kde by to mohlo být problémem.

    Operátor @ používám ve dvou případech - pokud lze chybu zanedbat nebo pokud mám chybu ošetřenou jinak.

    <OT>Tlačítka pro reakci by již měla být umístěna logičtěji a neměla by způsobovat problém - už jsem to vyřešil.</OT>

    24.1.2008 19:38:01
    21

Máte jiný názor než já? Spletl jsem se někde? Něco jsem zapoměl? Něco chcete doplnit? Nebo chcete jen reagovat na jiný komentář? Tak od toho to tu je diskuze!

Pravidla

Formátování

Používají se tu následující způsoby formátování:

jméno
web autora
text

Linkování

Líbí se Vám tato stránka? Zalinkujte ji!

Chcete sledovat novinky? Pokud si právě prohlížíte článek a hledáte RSS pro celý web, pak jste trošku jinde. Možná hledáte poslední změny.

Validní HTML 4.01 StrictValidní CSS 2.0Validní hlavní RSS kanálPHP 5Apache
referer: UA:CCBot/2.0 (http://commoncrawl.org/faq/) time:0.94203000 1505982984
web
mail
comment