NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Lekce 6 - SqlDataReader a připojená databáze ve VB.NET

V předchozím kvízu, Kvíz - Databáze, přístupy, připojená aplikace ve VB-ADO.NET , jsme si ověřili nabyté zkušenosti z předchozích lekcí.

V dnešním Databáze - ADO.NET tutoriálu, v jazyce VB.NET, se naučíme číst řádky z databáze pomocí třídy SqlDataReader a používat parametrizované dotazy, které znemožňují útok SQL injection.

Pracujeme s databází z lekce Vytvoření lokální databáze ve Visual Studio ve VB.NET, kterou v jednotlivých lekcích upravujeme. 

Čtení dat

Pokud potřebujeme spustit nad databází dotaz, který vrací více záznamů (ten náš poslední vracel jen jedno číslo), musíme ke zpracování výsledku dotazu využít třídu SqlDataReader. Instanci této třídy jako výsledek vrátí metoda ExecuteReader() třídy SqlCommand.

Třída SqlDataReader umožňuje procházet výslednou množinu dat po jednotlivých záznamech. K tomu slouží metoda Read(). Přístup k jednotlivým atributům záznamu můžeme získat pomocí indexu nebo názvu sloupce uvedeného v kulatých závorkách.

Výpis slovíček

Napíšeme si kód pro vypsání všech slovíček z naší databáze:

Using pripojeni As SqlConnection = New SqlConnection(connectionString)
    pripojeni.Open()
    Dim prikaz As SqlCommand = New SqlCommand("SELECT Id, Czech, English FROM Word", pripojeni)
    Dim dataReader As SqlDataReader = prikaz.ExecuteReader()
    While dataReader.Read()     ' dokud neprojdeme všechny záznamy
        Console.WriteLine("{0} {1} {2}",
                dataReader(0),
                dataReader("Czech"),
                dataReader(2))
    End While
    pripojeni.Close()
End Using

Připojíme se k databázi metodou Open() a do proměnné prikaz sestavíme SQL dotaz. V cyklu While, na instanci dataReader typu SqlDataReader, postupně načítáme slovíčka metodou Read() a vypisujeme pro každý sloupec jeho:

  • index (Id) dataReader(0),
  • název dataReader("Czech"),
  • index (English) dataReader(2).

Výsledek:

Konzolová aplikace
1 počítač computer
2 míč ball
3 pes dog
4 já I
5 mít rád like
6 devbook devbook

Předávání parametrů

Udělejme z aplikace opravdový slovníček :-) a nechme uživatele zadat slovíčko, které mu následně přeložíme.

SQL injekce

Nejprve si ukažme, jak se to nemá dělat. Naivně bychom si mohli nechat zadat slovíčko, a to potom přímo vložit jako vyhledávanou frázi do dotazu. Zdrojový kód aplikace by vypadal takto:

' Tento zdrojový kód je nebezpečný.
Using pripojeni As SqlConnection = New SqlConnection(connectionString)
    pripojeni.Open()
    Console.WriteLine("Zadej anglické slovíčko k překladu")
    Dim slovo As String = Console.ReadLine()

    Dim prikaz As SqlCommand = New SqlCommand("SELECT Czech FROM Word WHERE English='" & slovo & "'", pripojeni)

    Dim dataReader As SqlDataReader = prikaz.ExecuteReader()
    While dataReader.Read()
        Console.WriteLine("Překlad: {0}", dataReader("Czech"))
    End While

    pripojeni.Close()
End Using

SQL dotaz je podobný tomu předchozímu. Nezajímají nás však již všechny řádky, ale jen ty, kde má sloupec English určitou hodnotu. Podmínku v SQL dotazu jsme zapsali pomocí klauzule WHERE.

Navenek aplikace funguje korektně:

Konzolová aplikace
Zadej anglické slovíčko k překladu
computer
Překlad: počítač

Zamysleme se nad tím, co se stane, když nějaký uživatel zadá k překladu tento řetězec:

'; DROP TABLE Word --

Škodlivý kód se nám vloží přímo do dotazu a spustí se nad databází. Útočníkovi tak dáváme plnou kontrolu nad našimi daty. V tomto případě nám nenávratně vymaže celou tabulku. A to je ještě poměrně nevinný útok, mohl by nám vzít i hesla uživatelů a podobně.

Bezpečnostní problém jsme způsobili přímým vkládáním hodnot do textu SQL dotazu. Útok se proto nazývá SQL injection, tj. vložení cizího SQL kódu do našeho. Musíme počítat s tím, že škodlivý kód může být v každém parametru, který do dotazu vkládáme. Nelze se spolehnout na to, že tato proměnná asi nebude nic od uživatele obsahovat.

Ochrana před SQL injekcí

V minulosti se parametry ošetřovaly speciální funkcí, která tzv. zescapovala škodlivé znaky. Moderní dotazy se píší pomocí tzv. Prepared Statements. Ty fungují tak, že se do dotazu místo parametrů vloží jen speciální značky. Parametry se poté předávají odděleně. Ukažme si, jak do dotazu vložit parametry správně:

Using pripojeni As SqlConnection = New SqlConnection(connectionString)
    pripojeni.Open()
    Console.WriteLine("Zadej anglické slovíčko k překladu")
    Dim slovo As String = Console.ReadLine()

    Dim prikaz As SqlCommand = New SqlCommand("SELECT Czech FROM Word WHERE English=@slovo", pripojeni)
    prikaz.Parameters.AddWithValue("@slovo", slovo)

    Dim dataReader As SqlDataReader = prikaz.ExecuteReader()
    While dataReader.Read()
        Console.WriteLine("Překlad: {0}", dataReader("Czech"))
    End While

    pripojeni.Close()
End Using

Všimněme si, že v SQL dotazu je jen zástupná značka, která se označuje zavináčem @ a libovolným názvem. Nepíšeme kolem ní ani apostrofy, ty jsou dodány později podle typu značky. Před zavoláním metody ExecuteReader() připojíme do dotazu parametry, v našem případě parametr @slovo, jehož hodnotou bude proměnná slovo. Databáze si sama parametry ošetří a nemusíme se bát, že by nám aplikaci někdo mohl nabourat.

V příští lekci, Databáze ve VB.NET - INSERT, UPDATE, DELETE a COUNT, se naučíme přidávat, mazat, editovat a počítat záznamy v MS-SQL databázi ve VB.NET pomocí ADO.NET a třídy SqlCommand.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 6x (1021.43 kB)
Aplikace je včetně zdrojových kódů v jazyce VB.NET

 

Předchozí článek
Kvíz - Databáze, přístupy, připojená aplikace ve VB-ADO.NET
Všechny články v sekci
Databáze ve VB.NET - ADO.NET
Přeskočit článek
(nedoporučujeme)
Databáze ve VB.NET - INSERT, UPDATE, DELETE a COUNT
Článek pro vás napsal Stanislav Zita
Avatar
Uživatelské hodnocení:
Ještě nikdo nehodnotil, buď první!
Aktivity