Jak rozpoznat a zabránit SQL injection

Co je SQL injection
SQL injection (SQLi) je jeden z nejstarších a nejnebezpečnějších typů útoků na webové aplikace. Útok funguje tak, že útočník vkládá škodlivý SQL kód do vstupních polí (formuláře, parametry URL, cookies), které aplikace používá k sestavování SQL dotazů do databáze. Pokud aplikace nevaliduje a neočistí uživatelský vstup před jeho vložením do SQL dotazu, útočník může dotaz zmanipulovat tak, aby četl, upravoval nebo mazal data z databáze.
Podle žebříčku OWASP Top 10 patří útoky typu injection už roky mezi tři nejkritičtější webové zranitelnosti. Úspěšný útok SQL injection může vést ke krádeži celé databáze (uživatelské účty, hesla, osobní údaje), úpravě nebo smazání dat, obejití autentizace (přihlášení bez hesla), spuštění příkazů na operačním systému serveru a úplnému kompromitování serveru.
Jak SQL injection funguje
Základní princip
Představte si přihlašovací formulář, který ověřuje uživatelské jméno a heslo. Aplikace sestavuje SQL dotaz, který vypadá přibližně takto: SELECT * FROM users WHERE username = 'zadané_jméno' AND password = 'zadané_heslo'. Pokud aplikace jednoduše vloží uživatelský vstup do dotazu bez jakékoli kontroly, útočník může do pole uživatelského jména zadat speciální hodnotu, která změní logiku dotazu. Například vstup obsahující apostrof následovaný SQL kódem může uzavřít řetězcový literál a přidat podmínku, která je vždy pravdivá, čímž obejde kontrolu hesla.
Typy útoků SQL injection
Existuje několik typů útoků SQL injection. In-band SQLi je nejběžnější, kdy útočník používá stejný komunikační kanál pro odeslání útoku i příjem výsledků. Dělí se na Error-based SQLi (využívá chybové hlášky databáze k získání informací) a Union-based SQLi (využívá operátor UNION ke spojení výsledků škodlivého dotazu s legitimním). Blind SQLi je typ, kdy útočník nevidí přímé výsledky, ale může informace odvodit na základě chování aplikace. Boolean-based blind SQLi posílá dotazy, které vracejí true nebo false, a odvozuje data znak po znaku na základě rozdílů v odpovědi. Time-based blind SQLi využívá funkce pauzy SQL (SLEEP, WAITFOR DELAY) k určení, zda je podmínka pravdivá, podle doby odezvy. Out-of-band SQLi využívá jiný kanál pro exfiltraci dat, například DNS nebo HTTP požadavky, které databáze odesílá na server útočníka.
Odhalování zranitelností SQL injection
Manuální testování
Nejjednodušší způsob, jak otestovat zranitelnosti SQL injection, je vkládání speciálních znaků do vstupních polí. Apostrof (') je první test – pokud aplikace vrátí chybu databáze, existuje potenciální zranitelnost. Dvojitý apostrof ('') by neměl způsobit chybu, pokud ji způsobil jeden. SQL komentáře (-- nebo #) lze použít k zakomentování zbytku dotazu. Logické operátory (OR 1=1, AND 1=2) mohou odhalit zranitelnosti typu boolean-based. Příkaz SLEEP ('; WAITFOR DELAY '0:0:5'--) odhalí zranitelnosti typu time-based, pokud stránka zpozdí svou odpověď.
Automatizované nástroje
Pro systematické testování použijte specializované nástroje. SQLMap je nejznámější open-source nástroj pro automatickou detekci a zneužití zranitelností SQL injection – podporuje všechny typy SQLi a většinu databází. Burp Suite Professional má vestavěný skener pro SQL injection a další webové zranitelnosti. OWASP ZAP je bezplatná alternativa k Burp Suite se solidním skenerem SQLi. Acunetix a Netsparker jsou komerční skenery webových zranitelností s pokročilou detekcí SQLi.
Známky kompromitace
Pokud máte podezření, že váš web už byl cílem SQL injection, zkontrolujte následující: neobvyklé záznamy v logách webového serveru (URL adresy s SQL klíčovými slovy), nové nebo upravené uživatelské účty v databázi (zejména administrátorské účty), upravená data bez vašeho vědomí, nové soubory na serveru (web shelly) a zvýšený provoz na konkrétní stránky s neobvyklými parametry. Projděte také logy databáze kvůli neočekávaným dotazům.
Prevence – Prepared Statements
Co jsou prepared statements
Prepared statements (parametrizované dotazy) jsou nejúčinnější ochranou proti SQL injection. Místo vkládání uživatelského vstupu přímo do SQL dotazu jako textu odděluje prepared statement strukturu dotazu od dat. Nejprve se definuje struktura dotazu se zástupnými symboly pro data a poté se data odešlou zvlášť. Databáze zachází s daty pouze jako s hodnotami, nikdy jako se SQL kódem, čímž je injection nemožná.
Implementace v různých jazycích
PHP s PDO (PHP Data Objects) používá metodu prepare() k přípravě dotazu se zástupnými symboly (:username, :password) a execute() s polem hodnot. Rozšíření MySQLi podporuje prepared statements se zástupnými symboly ? a bind_param() pro navázání hodnot s datovými typy. Python s sqlite3 nebo psycopg2 používá zástupné symboly ? nebo %s. Java používá třídu PreparedStatement s metodami setString(), setInt(). Knihovny Node.js jako mysql2 a pg podporují parametrizované dotazy se zástupnými symboly ? nebo $1. Bez ohledu na programovací jazyk je princip stejný – nikdy nespojujte uživatelský vstup se SQL dotazem jako řetězce.
Další metody prevence
Validace vstupu
Kromě prepared statements vždy validujte uživatelský vstup. Whitelist validace povoluje pouze očekávané hodnoty – pokud má pole obsahovat číslo, ověřte před zpracováním, že jde skutečně o číslo. U textových polí omezte povolené znaky, délku vstupu a formát (regex). Nikdy se nespoléhejte pouze na validaci na straně klienta (JavaScript), protože útočník ji může obejít – validace musí být implementována na serveru.
Stored Procedures
Stored procedures jsou SQL kód uložený a spouštěný na databázovém serveru. Pokud jsou správně napsané (bez dynamického SQL uvnitř procedury), poskytují další vrstvu ochrany, protože aplikace volá proceduru s parametry místo odesílání syrových SQL dotazů. Stored procedures však samy o sobě nejsou zárukou bezpečnosti – pokud procedury interně sestavují dynamické dotazy z parametrů, zranitelnost stále existuje.
ORM (Object-Relational Mapping)
ORM knihovny jako Eloquent (Laravel), SQLAlchemy (Python), Hibernate (Java) a TypeORM (Node.js) automaticky používají prepared statements pro všechny dotazy, čímž eliminují většinu rizika SQL injection. Většina ORM však umožňuje syrové SQL dotazy pro složité operace – v takových případech musíte prepared statements použít ručně. ORM nenahrazuje znalost bezpečnosti SQL, ale významně snižuje plochu pro útok.
Princip nejnižších oprávnění
Nakonfigurujte databázi tak, aby aplikace používala účet s minimálními nezbytnými oprávněními. Webová aplikace obvykle potřebuje oprávnění SELECT, INSERT, UPDATE a DELETE na konkrétních tabulkách. Neudělujte účtu aplikace oprávnění DROP, ALTER, CREATE ani FILE. Pokud útočník uspěje se SQL injection, omezená oprávnění zabrání mazání tabulek, úpravě struktury databáze a přístupu k souborovému systému serveru.
Ochrana před SQL injection pomocí WAF
Jak WAF detekuje SQLi
Web Application Firewall (WAF) analyzuje HTTP požadavky a blokuje ty, které obsahují vzory SQL injection. WAF rozpoznává SQL klíčová slova na neočekávaných místech (SELECT, UNION, DROP v parametrech URL), speciální znaky používané při útocích SQLi (apostrofy, komentáře, logické operátory), známé payloady SQLi z databáze signatur a anomálie ve struktuře požadavku, které naznačují pokus o injection.
Omezení WAF
WAF není náhradou za bezpečný kód. Zkušení útočníci mohou WAF obejít pomocí technik kódování (URL encoding, Unicode, double encoding), komentářů a mezer k narušení signatur, alternativních SQL syntaxí, které WAF nerozpozná, a postupného testování k určení, jaká pravidla WAF používá. WAF je další vrstva ochrany (defense in depth), ale primární ochrana musí být v kódu aplikace prostřednictvím prepared statements a validace vstupu.
SQL injection ve WordPressu
Ochranné mechanismy WordPressu
Jádro WordPressu používá pro všechny dotazy do databáze metodu $wpdb->prepare(), což je implementace prepared statements ve WordPressu. Tato metoda používá zástupné symboly ve stylu sprintf (%s pro řetězce, %d pro celá čísla, %f pro desetinná čísla) a automaticky escapuje hodnoty. Zranitelnosti se však nejčastěji objevují v pluginech a šablonách, které $wpdb->prepare() nepoužívají nebo sestavují dotazy ručním spojováním řetězců.
Ochrana webu na WordPressu
Chcete-li ochránit web na WordPressu před SQL injection, pravidelně aktualizujte jádro WordPressu, pluginy a šablony, protože bezpečnostní záplaty často řeší zranitelnosti SQLi. Používejte pouze pluginy a šablony z důvěryhodných zdrojů (repozitář WordPress.org, známí komerční poskytovatelé). Nainstalujte bezpečnostní plugin (Wordfence, Sucuri, iThemes Security), který zahrnuje ochranu WAF. Podívejte se také na našeho průvodce ochranou webu před hackery. Odstraňte nepoužívané pluginy a šablony, protože i deaktivované pluginy lze zneužít. Omezte přístup k databázi – WordPress potřebuje pouze jednoho uživatele s přístupem ke své databázi.
Časté chyby, které nechávají web zranitelný
- Dynamické SQL v kódu: Spojování uživatelského vstupu se SQL dotazem jako řetězce je hlavní příčinou zranitelností SQL injection. Vždy používejte prepared statements.
- Důvěra ve validaci na straně klienta: Validaci v JavaScriptu lze obejít – veškerá validace musí existovat na serveru.
- Podrobné chybové hlášky: Zobrazování SQL chyb uživatelům odhaluje strukturu databáze a usnadňuje útok. V produkci logujte chyby interně a uživatelům zobrazte obecnou hlášku.
- Zastaralý software: Staré verze CMS, frameworků a knihoven mají často známé zranitelnosti SQLi s veřejně dostupnými exploity.
- Jeden databázový uživatel pro vše: Použití root účtu pro aplikaci dává útočníkovi v případě úspěšného útoku plnou kontrolu nad databází.
Závěr
SQL injection je vážná hrozba, která může zcela kompromitovat váš web i data uživatelů. Prevence je poměrně jednoduchá – používejte prepared statements pro všechny interakce s databází, validujte uživatelský vstup na serveru, uplatňujte princip nejnižších oprávnění a udržujte software aktuální. WAF poskytuje další vrstvu ochrany, ale nenahrazuje bezpečný kód. U hostingu BeoHosting mají všechny servery nakonfigurovaný WAF ModSecurity, který detekuje a blokuje pokusy o SQL injection, ale doporučujeme, aby i váš kód dodržoval osvědčené postupy bezpečného programování.
BeoHosting Team
10+ let zkušeností — Specialisté na webhosting a infrastrukturu
- Web Hosting
- WordPress Hosting
- VPS
- Dedicated Serveri
- Domeni
- SSL
- cPanel
- LiteSpeed
- Linux administracija
- DNS
Naposledy aktualizováno: