close

SQL injekce

Přejít na navigaci Přejít na hledání
Image
Klasifikace webových útoků pomocí SQL injection

SQL injection je metoda infiltrace rušivého kódu, která využívá zranitelnost počítače přítomnou v aplikaci na úrovni ověření vstupu k provádění operací s databází . [ 1 ]

Původ této chyby zabezpečení spočívá v nesprávné kontrole nebo filtrování proměnných používaných v programu, který obsahuje nebo generuje kód SQL . Je to ve skutečnosti chyba z obecnější třídy zranitelností, která se může vyskytnout v jakémkoli programovacím jazyce nebo skriptu , který je zabudován v jiném.

Je známá jako SQL Injection, bez rozdílu, podle typu zranitelnosti, způsobu infiltrace, skutečnosti vkládání rušivého kódu SQL a části vloženého kódu.

Popis

Říká se, že vložení SQL existuje nebo k němu došlo, když je nějakým způsobem vložen nebo „vstříknut“ podvodný kód SQL do naprogramovaného kódu SQL, aby narušil normální provoz programu a způsobil tak provedení části kódu. „invader“ embedded , v databázi .

Tento typ narušení má obvykle zákeřnou, škodlivou nebo špionážní povahu, jedná se tedy o problém zabezpečení počítače a musí jej vzít v úvahu aplikační programátor , aby mu zabránil. Program vyvinutý nedbale , nedbale nebo s neznalostí problému se může ukázat jako zranitelný a nakonec může být ohrožena bezpečnost systému (databáze).

K průniku dochází během spouštění zranitelného programu, a to buď na stolních počítačích , nebo na webových stránkách , v druhém případě zjevně běžícím na serveru , který je hostí.

K této chybě zabezpečení může dojít automaticky, když program „nedbale sestaví“ příkaz SQL za běhu nebo během vývojové fáze, kdy programátor provede nechráněný příkaz SQL jako explicitní. V každém případě, kdykoli programátor potřebuje a využívá parametry zadávané uživatelem za účelem nahlédnutí do databáze; protože přesně v parametrech může být začleněn rušivý kód SQL.

Když je dotaz proveden proti databázi , provede se také vložený kód SQL , který může provádět řadu věcí, jako je vkládání záznamů, úprava nebo mazání dat, autorizace přístupu a dokonce spouštění jiných typů škodlivého kódu v počítači.

Za předpokladu, že se například následující kód nachází ve webové aplikaci a že existuje parametr „username“, který obsahuje uživatelské jméno, na které se má dotazovat, by mohla být injekce SQL spuštěna následovně:

Původní a zranitelný kód SQL je:

consulta := "SELECT * FROM usuarios WHERE nombre = '" + nombreUsuario + "';"

Pokud operátor napíše jméno, například "Pepe", nestane se nic neobvyklého, aplikace by vygenerovala SQL příkaz podobný následujícímu, což je naprosto správné, kde by byly všechny záznamy se jménem "Pepe" v databázi vybrané údaje:

SELECT * FROM usuarios WHERE nombre = 'Pepe';

Ale pokud škodlivý operátor zapíše jako uživatelské jméno do dotazu:

Alicia'; DROP TABLE usuarios; SELECT * FROM datos WHERE nombre LIKE '%

, vygeneruje se následující SQL dotaz (zelená barva je to, co programátor zamýšlí, modrá jsou data a červená je vložený kód SQL):

SELECT * FROM uživatelů WHERE name = ' Alice ';
uživatelé DROP TABLE;
SELECT * FROM data WHERE jméno LIKE '% ';

V databázi by se dotaz provedl v daném pořadí, vybraly by se všechny záznamy s názvem 'Alice', smazala by se tabulka 'uživatelé' a nakonec by se vybrala celá tabulka 'data', která by neměla být k dispozici pro běžné uživatele webu.

Stručně řečeno, jakákoli data v databázi mohou být zpřístupněna ke čtení nebo změně uživatelem se zlými úmysly.

Všimněte si, proč se nazývá SQL " Injection ". Pokud se podíváte na škodlivý kód, který je červený, všimnete si, že je vložen uprostřed dobrého kódu, který je zelený. Červený kód byl tedy „ vstříknut “ do zeleného.

Ve většině programovacích jazyků , které umožňují vývoj webových aplikací , se lze ze strany programátora snadno vyhnout SQL injection . Toto téma je stručně probráno v další části.

Blind SQL injection

Blind SQL injection je funkce a technika útoku, která využívá SQL injection . Projevuje se to, když webová stránka kvůli bezpečnostní chybě nezobrazuje chybové zprávy, protože při dotazování do databáze nejsou správné výsledky, vždy se zobrazuje stejný obsah (to znamená, že existuje odpověď pouze v případě, že je výsledek správný) Správně).

Podmíněné příkazy typu „Nebo 1=1“ nebo „mající 1=1“ nabízejí vždy správné odpovědi (true), proto je programátoři často používají jako formy ověření. Problém pro bezpečnost stránky spočívá v tom, že tato technika se používá v kombinaci se slovníky nebo hrubou silou pro hledání, znak po znaku, hesla, uživatelského jména, telefonního čísla nebo jakýchkoli jiných informací, které web hostuje. ; K tomu se používá specifický kód SQL , který „testuje“ každý znak a při shodě získá kumulativní pozitivní výsledek. Tímto způsobem můžete například vědět, že heslo začíná "F...", pak pokračuje ".i..." a poté "..r..." atd. (shromažďuje Fir.. . ), dokud nenajdete celé slovo.

Existují programy, které automatizují tento proces "sondování" písmeno po písmenu ve výsledku SQL dotazu, který by útočník mohl poslat injektovaný.

Některé způsoby, jak se vyhnout SQL Injection

Ruby on Rails

V rámci Ruby on Rails ( RoR) jsou dotazy automaticky ověřovány některou ze zahrnutých vyhledávacích metod. Například:

 Projekt . najít  dotaz  : =  "SELECT * FROM users WHERE name = '"  +  uživatelské jméno  +  "';" 
 # nebo 
 Projekt . najít ( :all ,  :conditions  =>  { :name  =>  parametry [ :name ] })

Jediný způsob, jak může uživatel se zlými úmysly použít SQL injection v RoR, je zakódovat proměnnou do řetězce a použít ji přímo jako argument hledání. Například:

 # TOTO BY SE NEMĚLO PROVÁDĚT 
 Projekt . najít ( :all ,  :conditions  =>  "name = ' #{ params [ :name ] } '" )

Perl

V jazyce Perl DBI metoda DBI::quote filtruje speciální znaky (za předpokladu, že proměnná $sql obsahuje odkaz na objekt DBI):

 $query  =  $sql -> připravit  
   (  
         "SELECT * FROM users WHERE name = "  
     .  
         $sql -> quote ( $username )  
    );

Nebo můžete také použít funkci zástupného symbolu (s automatickým uvozováním) takto:

 $query  =  $sql -> připravit ( "SELECT * FROM uživatele WHERE jméno = ?" );  
 $dotaz -> vykonat ( $username );

PHP

V jazyce PHP existují různé funkce, které vám mohou pomoci používat jej s různými systémy správy databází .

Pokud se používá MySQL , funkce, která se má použít, je mysql_real_escape_string :

 $query_result  =  mysql_query ( "SELECT * FROM users WHERE name = \" "  .  mysql_real_escape_string ( $username )  .  " \" " );

Doporučuje se však používat alternativy, které nabízejí připravené dotazy, jako je třída PDO .

$statement  =  $pdo -> připravit ( "SELECT * FROM users WHERE name = :name" ); 
$statement -> bindParam ( ':name' ,  $user_name ); 
$příkaz -> provést (); 
$výsledek  =  $příkaz -> načíst ();

A pokud se používá MySQLi...

// S funkcemi 
$connection  =  mysqli_connect ( "host" ,  "user" ,  "password" ,  "dbd" ); 
$query  =  mysqli_query ( $connection ,  "SELECT * FROM users WHERE name = '"  .  mysqli_real_escape_string ( $connection ,  $name )  .  "'" ); 
// Objektově orientované dědění třídy: 
$query  =  $this -> dotaz ( "SELECT * FROM users WHERE name = '"  .  $this -> real_escape_string (  $name  )  .  "'" ); 
// Bez zdědění třídy 
$query  =  $this -> mysqli -> dotaz ( "SELECT * FROM users WHERE name = '"  .  $this -> mysqli -> real_escape_string ( $name )  .  "'" ); 
/* kde $this->mysqli je odkaz mysqli na databázi */

Java

V jazyce Java lze použít třídu PreparedStatement

Namísto:

 Connection  con  =  ( získat  připojení )  
 Příkaz  stmt  =  con . createStatement ();  
 ResultSet  rset  =  stmt . executeQuery ( "SELECT * FROM users WHERE name = '"  +  uživatelské jméno  +  "';" );

lze použít parametrizaci nebo escapování proměnných, jak je uvedeno v následujících částech.

Parametrizace SQL příkazů

 Connection  con  =  ( získat  připojení )  
 PreparedStatement  pstmt  =  con . PrepareStatement ( "SELECT * FROM users WHERE name = ?" );  
 pstmt . setString ( 1 ,  uživatelské jméno );  
 ResultSet  rset  =  pstmt . executeQuery ();

Escape proměnné pro vložení do SQL příkazu

Escapování textu obsaženého v proměnné nahrazením speciálních znaků v SQL jejich textovým ekvivalentem, takže SQL interpretuje celý obsah proměnné, jako by to byl text.

 Connection  con  =  ( získat  připojení )  
 Příkaz  stmt  =  con . createStatement ();  
 ResultSet  rset  =  stmt . executeQuery ( "SELECT * FROM users WHERE name = '"  +  uživatelské jméno . nahradit ( "\\" ,  "\\\\" ). nahradit ( "'" ,  "\\'" )  +  "';" );

Můžete také použít metodu escapeSQL třídy z knihovny Apache Commons Lang .

 Connection  con  =  ( získat  připojení )  
 Příkaz  stmt  =  con . createStatement ();  
 ResultSet  rset  =  stmt . executeQuery ( "SELECT * FROM users WHERE Name = '"  +  StringEscapeUtils . escapeSQL ( UserName )  +  "';" );

V C#

V jazyce C# z platformy .NET (nebo její bezplatné alternativy Mono ) existuje ADO.NET SqlCommand (pro Microsoft SQL Server ) nebo OracleCommand (pro databázové servery Oracle). Následující příklad ukazuje, jak zabránit útokům vložení kódu pomocí objektu SqlCommand. Kód pro ADO.NET je naprogramován podobným způsobem, i když se může mírně lišit v závislosti na konkrétní implementaci každého dodavatele.

Namísto:

 using (  SqlConnection  con  =  ( získat  připojení )  )  {  
     con .  Otevřít ();  
     using (  SqlCommand  cmd  =  new  SqlCommand ( "SELECT * FROM users WHERE name = '"  +  username  +  "'" ,  with )  )  {  
        using (  SqlDataReader  rdr  =  cmd . ExecuteReader ()  ){  
            ...  
        }  
     }        
 }

lze použít následující:

 using (  SqlConnection  con  =  ( získat  připojení )  )  {  
     con .  Otevřít ();  
     using (  SqlCommand  cmd  =  new  SqlCommand ( "SELECT * FROM users WHERE name = @username" ,  with )  )  { 
 
        cmd . parametry . AddWithValue ( "@uživatelské jméno" ,  uživatelské jméno ); 
 
        pomocí (  SqlDataReader  rdr  =  cmd . ExecuteReader ()  ){  
            ...  
        }  
     }        
 }

Viz také

Reference

  1. "SQL Injection | OWASP» . owasp.org (v angličtině) . Staženo 13. září 2021 . 

Externí odkazy