SQL injekce je jednoduchý vektor útoku, který je stále velmi běžný. Důvodem není nic jiného než absence patche pro hloupost. Proč to říkáte, vezměme si jako příklad JAVA, abychom to ilustrovali:
Předpokládejme, že v databázi existuje tabulka tohoto typu:
Poté použijte tabulku akcí JDBC:
Výše uvedený kód často používají někteří vývojáři. Představte si situaci, kdy příchozí parametr userId je "3; uživatel tabulky drop; SQL příkaz vykonáný je následující:
Po zkompilování a spuštění databáze je uživatelská tabulka smazána. Voilà, jednoduchý útok SQL injection nastává účinku! Je to proto, že výše uvedený kód neodpovídá programovacím specifikacím.
Když programujeme podle specifikace, SQL injekce neexistuje. To platí iPrvní způsob, jak se vyhnout SQL injection: předkompilované příkazy, kód je následující:
Proč v uvedeném kódu neexistuje SQL injection? Protože je použit předkompilovaný příkaz, předkompilovaný příkaz nastaví "select name from user where id= ?" Příkaz je zkompilován předem, takže stačí při spuštění nahradit pouze příchozími parametry? Zástupné funkce jsou v pořádku. V prvním případě nesouladu program napíše SQL příkaz a poté jej zkompiluje s obsahem předaným uživatelem, což je přesně ten problém.
Kromě použití předkompilovaných příkazů existuje druhá možnostZpůsoby, jak se vyhnout útokům SQL injection: Uložené procedury。 Uložená procedura je sada SQL příkazů, které vykonávají specifickou funkci, zkompilované a uložené v databázi, a uživatel ji může spustit zavoláním uložené procedury a zadáním parametru (pokud uložená procedura má parametry), což může také zabránit útokům SQL injection
Odpovídající uložená procedura v uvedeném kódu je následující:
Samozřejmě uživatelé mohou také provádět kontrolu znaků na frontendu, což je také způsob, jak se vyhnout SQL injection: například u parametru userId výše uživatel zkontroluje středník a zobrazí se chyba. Nejzákladnějším důvodem však je, že SQL injection útoky existují proto, že aplikace nepoužívají least privilege při přístupu k databázím. Zdá se, že všichni používají root účet k přístupu k databázi.
Jak se MyBatis vyhne útokům SQL injection? Nebo vezměme uživatele tabulky výše jako příklad: Řekněme, že mapper soubor je:
Odpovídající java soubory jsou:
Vidíte, že vstupní parametr je userId typu String, když předáme userId="34; uživatel tabulky drop; Poté tištěné prohlášení zní:
Bez ohledu na zadané uživatelské ID je jeho SQL příkaz takto. Je to způsobeno tím, že mybatis používá předkompilované příkazy v základní implementaci. Když databáze vykoná toto tvrzení, přímo použije předkompilovaný příkaz a pak nahrazuje zástupce procházejícím userId? Prostě běž. Nejdřív vyměnit zástupné záložky? Proces kompilace probíhá, takže není prostor pro SQL injection.
Jak tedy MyBatis provádí předkompilaci SQL? Ve skutečnosti se třída PreparedStatement používá na spodní části rámce. Třída PreparedStaement nejenže zabraňuje SQL injekci, ale také šetří (N-1) čas kompilace, když je stejný SQL příkaz vykonán nkrát, čímž se zvyšuje efektivita.
Pokud změníte výše uvedené tvrzení na:
Když zadáme userId="34; uživatel tabulky drop; Poté tištěné prohlášení zní:
V tuto chvíli mybatis nepoužívá předkompilované příkazy, nejprve spojí řetězce a poté provede kompilaci, což je přesně způsob, jakým se SQL injection projeví.
Proto při psaní příkazů pro mapování mybatis se snažte použít formát "#{xxx}". Pokud musíte použít parametry jako "${xxx}", musíte je ručně filtrovat, abyste zabránili SQL injekčním útokům.
|