SQL Injection je bezpečnostní chyba ve webových aplikacích, kam útočníci vkládají škodlivý kód SQL prostřednictvím uživatelského vstupu. To jim může umožnit přístup k citlivým datům, měnit obsah databáze nebo dokonce převzít kontrolu nad systémem. Je důležité vědět o SQL Injection, aby byly webové aplikace zabezpečené.
SQL Injection (SQLi) je bezpečnostní chyba, ke které dochází, když útočník může manipulovat s databázovými dotazy webové aplikace vložením škodlivého kódu SQL do uživatelských vstupních polí. Tyto vložené dotazy mohou manipulovat se základní databází za účelem získání úprav nebo odstranění citlivých dat. V některých případech mohou útočníci dokonce eskalovat oprávnění a získat tak plnou kontrolu nad databází nebo serverem.

Příklad ze skutečného světa:
V roce 2019 došlo k narušení dat Capital One kvůli špatně nakonfigurované webové aplikaci, která umožnila útočníkovi zneužít chybu zabezpečení vkládání SQL. To vedlo k úniku osobních údajů více než 100 milionů zákazníků, včetně jmenných adres a kreditního skóre.
Úroveň zabezpečení SQL Injection
DVWA poskytuje čtyři úrovně zabezpečení pro SQL Injection, aby studentům pomohla vidět, jak různé ochrany ovlivňují útoky:
1. Nízká bezpečnost
Aplikace převezme váš vstup a vloží ho přímo do SQL dotazu bez filtrování.
$id = $_GET['id'];$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';- Zadání
':Přeruší dotaz a způsobí, že databáze vyvolá chybu, která odhalí, že je zranitelná. - Zadání
1' OR '1'='1:Oklame dotaz tak, aby byl vždy pravdivý, takže jsou vráceni všichni uživatelé. - Zadání
1' UNION SELECT user password FROM users--:Připojí se k dalšímu dotazu a načte skrytá data, jako jsou uživatelská jména a hesla.
2. Střední zabezpečení
Aplikace aplikuje základní vstupní sanitaci pomocí funkcí jakoaddslashes()uniknout'.
$id = addslashes($_GET['id']);$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';Jak může být útok:
Jednoduché'injekce již nebude fungovat (protože se stane').
Útočníci se však stále mohou obejít pomocí numerické injekce (protože čísla nepotřebují uvozovky).
Příklad:
kat timpf hmotnost
1 OR 1=1To stále vrací všechny záznamy.
3. Vysoká bezpečnost
Aplikace používá připravené příkazy (parametrizované dotazy) k bezpečnému zpracování uživatelského vstupu.
$stmt = $pdo->prepare('SELECT first_name last_name FROM users WHERE user_id = ?');$stmt->execute([$id]);Útok:
Pokusy jako' OR 1=1neboUNION SELECTuž nepracuje.
Dotaz považuje veškerý vstup za data, nikoli za kód SQL.
Typy SQL Injection
Existují různé typy SQL Injection
1. Chybová injekce SQL
Injekce SQL založené na chybě je typ in-band SQL injection, kdy útočník úmyslně způsobí, že databáze vygeneruje chybovou zprávu. Útočník pak analyzuje tuto chybovou zprávu, aby získal cenné informace o struktuře databáze, jako jsou názvy tabulek a názvy sloupců, které lze použít k vytvoření dalších přesnějších útoků.
Jak to funguje
Tento útok se zaměřuje na aplikace, které odhalují nezpracované chyby databáze namísto zobrazování obecných zpráv. Vložením škodlivého vstupu, který narušuje syntaxi SQL, útočníci spouštějí tyto chyby a získávají cenné vodítka o struktuře databáze.
věk kylie jenner
- Identifikujte zranitelný vstup: Útočník najde vstupní pole, jako je vyhledávací panel nebo parametr adresy URL, který přímo interaguje s databází bez řádné dezinfekce vstupu.
- Vložení škodlivého nákladu: Útočník vloží speciální znak (jako jednu uvozovku
') nebo funkce, o které je známo, že způsobuje chybu databáze. - Analyzujte chybu: Databáze, která nemůže zpracovat chybně naformátovaný dotaz, vrátí podrobnou chybovou zprávu. Tato zpráva může odhalit důležité informace, jako jsou:
- Databázový systém (např. MySQL Oracle SQL Server).
- Verze databáze.
- Probíhá úplný SQL dotaz.
- Specifické chyby syntaxe, které lze použít k pochopení názvů tabulek nebo sloupců.
- Upřesněte útok: Pomocí informací shromážděných z chybové zprávy může útočník upřesnit své užitečné zatížení a získat další data, jako jsou uživatelská jména a hesla.
Příklad:
Krok 1: Nastavte své prostředí
- Spusťte DVWA. Obvykle je přístupný přechodem na adresu URL, jako je
http://localhost/dvwave vašem prohlížeči.
- Přihlaste se do DVWA pomocí výchozích přihlašovacích údajů:
admin/password.
- Přejděte na kartu Zabezpečení DVWA a nastavte úroveň zabezpečení na nízkou. To zajistí, že zranitelnosti budou snadno zneužitelné.
Krok 2: Identifikujte zranitelnost
Stránka SQL Injection má jednoduché vstupní pole, kam můžete zadat ID uživatele. Backendový dotaz je pravděpodobně něco podobnéhoSELECT * FROM users WHERE id = 'user_input'
- Zadejte platné ID jako
1do vstupního pole a klikněte na tlačítko Odeslat. Měli byste vidět podrobnosti o uživateli s ID 1.
Zdroj SQL Injection
PHP $id = $_REQUEST[ 'id' ]; switch ($_DVWA['SQLI_DB']) { case MYSQL: // Check database $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; $result = mysqli_query($GLOBALS['___mysqli_ston'] $query ) or die( ''
. ((is_object($GLOBALS['___mysqli_ston'])) ? mysqli_error($GLOBALS['___mysqli_ston']) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '' ); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo 'ID:
{$id}
First name: {$first}
Surname: {$last}'; } mysqli_close($GLOBALS['___mysqli_ston']); break; case SQLITE: global $sqlite_db_connection; #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']); #$sqlite_db_connection->enableExceptions(true); $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; #print $query; try { $results = $sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo 'ID:
{$id}
First name: {$first}
Surname: {$last}'; } } else { echo 'Error in fetch '.$sqlite_db->lastErrorMsg(); } break; } } ode ?> - Nyní zkuste přerušit dotaz. Zadejte jedinou nabídku
'do vstupního pole a odeslat.
Dotaz se stává:
SELECT * FROM users WHERE id = ''';Zde databáze vidí nabídku navíc a neví, jak dotaz dokončit.
propojený seznam v Javě
Místo zobrazení podrobností o uživateli aplikace vrátí chybu SQL (něco jako 'Máte chybu v syntaxi SQL...')
Toto se nazývá injekce SQL založená na chybě, protože:
- Útočník odešle neplatný vstup (
') - Databáze vyvolá chybu
- Tato chyba uniká užitečné informace o databázi (jako je typ struktury počtu sloupců DB atd.)
2. Union-Based SQL Injection
Union-based SQL Injection je technika, kde útočníci používajíUNIONoperátor pro spojení výsledků dvou nebo víceSELECTpříkazy do jedné sady výsledků. To jim může umožnit extrahovat informace z jiných tabulek v databázi. TheUNIONoperátor lze použít pouze v případě, že:
- Oba dotazy mají stejný počet sloupců
- Sloupce mají podobné datové typy
- Sloupce jsou ve stejném pořadí
Operátor UNION : TheUNIONoperátor se používá ke zkombinování sady výsledků dvou nebo víceSELECTprohlášení.
- Každý
SELECTprohlášení uvnitřUNIONmusí mít stejný počet sloupců - Sloupce musí mít podobné datové typy
- Sloupce musí být ve stejném pořadí
SELECT column_name(s) FROM table1UNIONSELECT column_name(s) FROM table2Příklad:
Krok 1: Nejprve musíme najít počet sloupců existující tabulky na webu, abychom vložili injekci SQL založenou na UNION:
Stránka SQL Injection má jednoduché vstupní pole, kam můžete zadat ID uživatele. Backendový dotaz je pravděpodobně něco podobného
SELECT * FROM users WHERE id = 'user_input'Nyní zkuste přerušit dotaz. Zadejte jedinou nabídku'do vstupního pole a odeslat.
Pokud je aplikace zranitelná, zobrazí se podrobná chybová zpráva. Mohlo by to vypadat nějak takto:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1
Krok 2: PoužijteUNIONKlíčové slovo pro zjištění počtu sloupců
Chcete-li použítUNIONklíčové slovo (běžný další krok) potřebujete znát počet sloupců v původním dotazu. Můžete to zjistit pomocíORDER BYdoložka
jméno města v usa
- Pokuste se seřadit výsledky podle sloupců
1:1 ORDER BY 1.
- Předložit. Mělo by to fungovat.
Zdroj SQL Injection
PHP if( isset( $_REQUEST[ 'Submit' ] ) ) { // Get input $id = $_REQUEST[ 'id' ]; switch ($_DVWA['SQLI_DB']) { case MYSQL: // Check database $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; $result = mysqli_query($GLOBALS['___mysqli_ston'] $query ) or die( ''
. ((is_object($GLOBALS['___mysqli_ston'])) ? mysqli_error($GLOBALS['___mysqli_ston']) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '' ); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo 'ID:
{$id}
First name: {$first}
Surname: {$last}'; } mysqli_close($GLOBALS['___mysqli_ston']); break; case SQLITE: global $sqlite_db_connection; #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']); #$sqlite_db_connection->enableExceptions(true); $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; #print $query; try { $results = $sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo 'ID:
{$id}
First name: {$first}
Surname: {$last}'; } } else { echo 'Error in fetch '.$sqlite_db->lastErrorMsg(); } break; } } ?> - Zvyšte číslo:
1 ORDER BY 2. Předložit. Mělo by to fungovat.
- Pokračujte ve zvyšování, dokud se nezobrazí chyba. Například
1 ORDER BY 4vám může dát:Unknown column '4' in 'order clause' - To znamená, že dotaz má 3 sloupce.
3. Blind-Based SQL Injection
Blind SQL Injection dochází, když útočníci nevidí výsledky dotazu přímo na webové stránce. Místo toho odvozují informace z jemných změn v chování aplikace nebo době odezvy. I když je pomalejší a zdlouhavější než klasické SQLi, může být stejně efektivní.
Místo získávání dat zpět útočník vyvozuje informace sledováním chování webové stránky. To se obvykle provádí jedním ze dvou způsobů:
- Blind SQLi na booleovských základech: Útočník vloží dotaz SQL, který vrátí a věrný nebo falešný výsledek. Odpověď webové aplikace se mění podle toho, zda je dotaz pravdivý nebo nepravdivý. Stránka může například zobrazit jinou zprávu nebo vykreslit jiné rozvržení.
- Časově orientované slepé SQLi: Útočník vloží dotaz SQL, který způsobí, že databáze provede časově náročnou akci (např
SLEEP()funkce), pokud je splněna podmínka. Útočník sleduje dobu, kterou trvá načtení stránky, aby určil, zda byla vložená podmínka pravdivá nebo nepravdivá.
Příklad:
Představte si přihlašovací stránku, kam zadáte uživatelské jméno a heslo. Aplikace vytvoří dotaz SQL takto:
SELECT * FROM users WHERE username = 'user_input' AND password = 'password_input'Slepá injekce SQL by zahrnovala manipulaci suser_inputpole pro položení otázky databázi.
Místo získání přímé odpovědi může útočník zkusit něco takového:
user_input = 'admin' AND 1=1; --Pokud se stránka načte normálně, útočník to ví1=1je a věrný prohlášení.
user_input = 'admin' AND 1=2; --Pokud stránka zobrazuje chybu nebo se chová jinak, útočník to ví1=2je a falešný prohlášení.
Pomocí řady těchto pravdivých/nepravdivých otázek může útočník systematicky hádat a extrahovat informace jeden znak po druhém. Proces lze zautomatizovat a uhodnout vše od názvů tabulek po uživatelská hesla.
Dopad útoků SQL Injection
- Neoprávněný přístup k citlivým údajům : Útočníci mohou získat osobní finanční nebo důvěrné informace uložené v databázi.
- Problémy s integritou dat : Útočníci mohou upravit, odstranit nebo poškodit důležitá data ovlivňující funkčnost aplikace.
- Eskalace privilegií : Útočníci mohou obejít autentizační mechanismy a získat administrátorská oprávnění.
- Prostoj služby : Injekce SQL může přetížit server a způsobit snížení výkonu nebo selhání systému.
- Poškození reputace : Úspěšný útok může vážně poškodit pověst organizace, což vede ke ztrátě důvěry zákazníků.
Prevence útoků SQL Injection
Existuje několik osvědčených postupů, jak zabránit útokům SQL injection:
1. Použijte připravené výpisy a parametrizované dotazy
Připravené příkazy a parametrizované dotazy zajišťují, že uživatelské vstupy jsou považovány za data, nikoli za součást SQL dotazu. Tento přístup eliminuje riziko vložení SQL.
pokud rudyardem kipling řádek po řádku vysvětlení
Příklad v PHP (pomocí MySQLi):
$stmt = $conn->prepare('SELECT * FROM users WHERE username = ? AND password = ?'); $stmt->bind_param('ss' $username $password); $stmt->execute();2. Použijte uložené procedury
Uložené procedury jsou předdefinované SQL dotazy uložené v databázi. Tyto postupy mohou pomoci zabránit vkládání SQL, protože dynamicky nevytvářejí dotazy SQL.
Příklad:
CREATE PROCEDURE GetUserByUsername (IN username VARCHAR(50)) BEGIN SELECT * FROM users WHERE username = username; END;3. Ověření vstupu na Whitelist
Zajistěte, aby byly uživatelské vstupy před použitím v dotazech SQL ověřeny. Povolte pouze určité znaky a vzory, jako je alfanumerický vstup pro pole, jako jsou uživatelská jména nebo e-mailové adresy.
4. Používejte rámce ORM
Objektově-relační mapování (ORM) rámce jako Přezimovat nebo Entity Framework může pomoci zabránit vkládání SQL tím, že automaticky zpracovává generování dotazů a zabraňuje dynamické konstrukci dotazů.
5. Omezte databázová oprávnění
Udělte uživatelům minimální požadovaná databázová oprávnění. Zajistěte, aby aplikace mohly provádět pouze nezbytné akce (např. SELECT INSERT) a omezte oprávnění jako DROP TABLE nebo ALTER.
6. Zpracování chyb
Nakonfigurujte databázi a aplikaci tak, aby uživateli nezobrazovaly podrobné chybové zprávy. Místo toho protokolujte chyby interně a zobrazujte obecné chybové zprávy koncovým uživatelům.