Proč používat parametry?

Tomáš Herceg       31.12.2008             10585 zobrazení

Dnes ráno jsem si všimnul dotazu ohledně parametrů v MySQL na zdejším fóru. Tazatel se ptal, jak v MySQL pracovat s parametry, načež mu bylo odpovězeno, že má SQL normálně poskládat.

Vřele doporučuji nikdy SQL dotazy neskládat, zaděláváte si tím na bezpečtnostní problém.

Skládat SQL dotaz je nebezpečné, protože pokud to neuděláte správně v celé aplikaci a byť jen na jednom místě zapomenete na patřičná ošetření, máte v aplikaci nezpečnostní díru.

Představte si následující situaci - ve webové aplikaci kontrolujete u přihlašovacího formuláře jména a hesla takto: "SELECT * FROM Users WHERE Uzivatel = '" + user + "' AND Heslo = '" + pass + "'". No a co udělá každý hacker? Zkusí jako uživatelské jméno dosadit tohle (bez uvozovek): "admin' –".

No a co se nestane? Apostrof ukončí řetězcový literál a za ním jsou dvě pomlčky, což znamená komentář - zbytek dotazu se tedy bude ignorovat. A uživatel má práva admina. Pokud to bude zlomyslný hacker, nedá za apostrof komentář, ale středník a pak tam přidá pár dalších příkazů, které mu z databáze vykopírují citlivá data uživatelů, nebo vám tam dá rovnou DELETE na všechny tabulky, co najde.

Jistě, dá se to ošetřit, málokdy ovšem stačí odstranit jen apostrofy (jsou i jiné způsoby, jak z literálu vyskočit). Každá knihovna pro práci s databází má funkci, která tohle nějak zařídí (v PHP např. známá mysql_real_escape_string). Jenže stačí, abyste v jednom dotazu zapomněli řetězec touto nebo podobnou funkcí prohnat a je konec. Právě proto se používají parametry - zaprvé pokud je striktně používáte všude (a na to jen tak nezapomenete), nemusíte se tohoto útoku vůbec bát, a zadruhé nemusíte se nemusíte starat o převádění datumu do formátu, v jakém ho chce databáze, to si většinou udělá už knihovna sama v okamžiku, kdy jí hodnotu parametru předáte. Naučte se tedy používat parametry.

Jak se to dělá v MS SQL?

Vytvoříme si klasicky připojení k databázi a klasický SqlCommand. V dotazu na místa, kam chceme něco dosazovat, umístíme parametry – před jejich názvem musí být @. My zde pro ukázku máme třeba @Datum. Pak pomocí volání com.Parameters.AddWithValue řekneme název parametru (už bez zavináče na začátku) a jeho hodnotu.

        Using con As New SqlConnection("connection string")
            Using com As New SqlCommand("SELECT * FROM Tabulka WHERE Datum > @Datum", con)
                com.Parameters.AddWithValue("Datum", Now)
                con.Open()

                'klasické zpracování výsledku

                con.Close()
            End Using
        End Using

A když už jsme u toho, nezapomínejte uzavírat spojení s databází. Spojení k databázi se berou z tzv. connection poolu, což je takový “bazének”, kde se spojení čvachtají, ráchají a hlavně čekají, až si je někdo vezme. Je jich ale omezený počet a pokud je nezavřete, do bazénku se nevrátí a nejsou k dispozici. Za chvíli tedy dojdou a aplikace začne padat.

A samozřejmě v tomto příkladu nejsou ošetřené výjimky, na druhou stranu pokud máte aplikaci správně napsanou, jediná možnost, kdy výjimka může nastat, je většinou pouze to, že databáze spadla nebo se k ní nedá připojit, a pak už je nejlepší napsat uživateli pouze výchozí chybovou stránku, protože stejně nemůžete nic rozumného udělat. Já tedy používám výjimky pouze tam, kde dělám nějaké složitější operace s daty (transakce atd.). U jednoduchých selectů je to celkem zbytečné.

Kdy parametry použít nejdou?

V opravdu mizivém procentu případů parametry použít nejdou, protože potřebujete SQL příkaz měnit nějak brutálněji, např. dynamicky určit název tabulky nebo sloupce, který se použije. Tam se parametr dát samozřejmě nedá. V takovém případě hlavně nenechte zadávat název tabulky přímo uživatele a buďte maximálně opatrní.

Tohle ale člověk většinou nepotřebuje tak často, já osobně stejně klasické selecty moc nepoužívám a většinu toho řeším pomocí uložených procedur v databázi.

 

hodnocení článku

0       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

Diskuse: Proč používat parametry?

http://sqlite.phxsoftware.com/forums/t/8...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: Proč používat parametry?

Navíc myslím, že je pro DB stroj snadnější optimalizovat/cachovat dotazy s parametry...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: Proč používat parametry?

Příklad nahoře je sice odstrašující, já si ale myslím, že trochu mixujeme dvě věci:

1) Ošetření dat zadaných uživatelem.

2) Ošetření dat posílaných databázi.

V tom příkladě nahoře by to šlo rověž ošetřit tak, že by se data nějak "oescapovala" tak, aby to databáze nepochopila jako komentář. Používá se to celkem často.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jistě, na druhou stranu hrozí, že zapomenete. Pokud striktně všude používáte parametry, tohle se vám nemůže stát, proto se obecně doporučuje všude parametry používat.

Něco jiného je pak ošetření toho, aby uživatel neposlal do DB třeba HTML, které se pak ve webové aplikaci dostane přímo do stránky, ale to už je zase jiná věc, tady samozřejmě parametry nepomohou.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Navržené řešení s poskládaným SELECTem, které Vás inspirovalo k napsání tohoto článku, pochází z jedné mé starší desktopové aplikace, kde si dotaz skládám za použití lokální celočíselné proměnné, kterou si sám plním přiřazovacím příkazem a následně okamžitě použiji. V tomto případě žádné bezpečnostní riziko nehrozí. Určitě máte pravdu, že striktní dodržování principů (zejména bezpečnostních) nás výrazně ochrání před možnými následky. Na druhou stranu daleko nebezpečnější je neuvědomování si rizika použitých metod a prostředků. (Platí obecně, proto je podél silnic tolik smutných křížků se jmény...)

Teď dělám s MS SQL a samozřejmě používám výhradně parametry a uložené procedury.

Jinak parametrizované dotazy by měly jít ve starém klasickém ADO (jež tazatel v daném příspěvku používá) řešit pomocí QueryDef.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: Proč používat parametry?

No, o tomhle problému jsem už psal...

http://vbnet.cz/clanek--52-komunikace_s_...

Ale nemyslím si, že nepoužití parametru, pokud je hodnota číslo je velký prohřešek. Jasně, ve větších projektech by to měl být zvyk, ale hlavní je, jestli si je programátor rizika vědom.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

U čísla to ještě jde, ale i tak, jednou zapomeneš a jsi nahraný.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback