SQL injekcija ir vienkāršs uzbrukuma vektors, kas joprojām ir ļoti izplatīts mūsdienās. Iemesls tam nav nekas cits kā stulbs plāksteris. Kāpēc jūs to sakāt, ņemsim JAVA kā piemēru, lai ilustrētu:
Pieņemsim, ka datu bāzē ir šāda tabula:
Pēc tam izmantojiet JDBC darbību tabulu:
Iepriekš minēto kodu bieži izmanto daži izstrādātāji. Iedomājieties situāciju, kad ienākošais userId parametrs ir "3; nomešanas tabulas lietotājs; Izpildītais SQL paziņojums ir šāds:
Pēc datu bāzes kompilēšanas un izpildes lietotāja tabula tiek izdzēsta. Voila, vienkāršs SQL injekcijas uzbrukums stājas spēkā! Tas ir tāpēc, ka iepriekš minētais kods neatbilst programmēšanas specifikācijām.
Kad mēs programmējam saskaņā ar specifikāciju, SQL injekcija nepastāv. Tas attiecas arī uzPirmais veids, kā izvairīties no SQL injekcijas: iepriekš kompilēti paziņojumi, kods ir šāds:
Kāpēc iepriekš minētajā kodā nav SQL injekcijas? Tā kā tiek izmantots iepriekš kompilētais priekšraksts, iepriekš kompilētais priekšraksts iestatīs "atlasīt vārdu no lietotāja, kur id= ?" Paziņojums tiek sastādīts iepriekš, lai tas tiktu aizstāts tikai ar ienākošajiem parametriem, kad tas tiek izpildīts? Vietturi ir labi. Pirmajā neatbilstošajā gadījumā programma uzrakstīs SQL paziņojumu un pēc tam apkopos to ar lietotāja nodoto saturu, kas ir tieši problēma.
Papildus iepriekš kompilētu paziņojumu izmantošanai ir arī otra iespējaVeidi, kā izvairīties no SQL injekcijas uzbrukumiem: saglabātās procedūras。 Saglabātā procedūra ir SQL paziņojumu kopums, kas veic noteiktu funkciju, kas apkopota un saglabāta datu bāzē, un lietotājs to var izpildīt, izsaucot saglabātu procedūru un norādot parametru (ja saglabātajai procedūrai ir parametri), kas var arī izvairīties no SQL injekcijas uzbrukumiem
Atbilstošā saglabātā procedūra iepriekš minētajā kodā ir šāda:
Protams, lietotāji var arī veikt rakstzīmju pārbaudi priekšgalā, kas ir arī veids, kā izvairīties no SQL injekcijas: piemēram, iepriekš minētajam userId parametram lietotājs pārbaudīs, vai nav semikola, un tiks parādīta kļūda. Tomēr vissvarīgākais iemesls ir tas, ka SQL injekcijas uzbrukumi pastāv, jo lietotnes, piekļūstot datu bāzēm, neizmanto vismazākās privilēģijas. Šķiet, ka visi ir izmantojuši saknes kontu, lai piekļūtu datu bāzei.
Tātad, kā MyBatis izvairās no SQL injekcijas uzbrukumiem? Vai arī ņemiet iepriekš minēto tabulas lietotāju kā piemēru: Pieņemsim, ka kartētāja fails ir:
Atbilstošie java faili ir:
Jūs varat redzēt, ka ievades parametrs ir String tipa userId, kad mēs nododam userId="34; nomešanas tabulas lietotājs; Pēc tam drukātajā paziņojumā ir rakstīts:
Neatkarīgi no ievadītā lietotāja ID, viņa sql paziņojums ir šāds. Tas ir saistīts ar to, ka mybatis pamatā esošajā ieviešanā izmanto iepriekš kompilētus paziņojumus. Kad datu bāze izpilda šo priekšrakstu, tā tieši izmanto iepriekš kompilēto priekšrakstu un pēc tam aizstāj vietturi ar pārejošo userId? Vienkārši ej skriet. Vispirms nomainīt vietturus? Kompilācijas process tiek veikts, tāpēc SQL injekcijai nav vietas, lai izdzīvotu.
Tātad, kā MyBatis veic SQL iepriekšēju kompilāciju? Faktiski PreparedStatement klase tiek izmantota sistēmas apakšā. Sagatavotā Staement klase ne tikai izvairās no SQL injekcijas, bet arī ietaupa (N-1) kompilācijas laiku, kad viens un tas pats SQL priekšraksts tiek izpildīts N reizes, tādējādi uzlabojot efektivitāti.
Ja maināt iepriekš minēto paziņojumu uz:
Ievadot userId="34; nomešanas tabulas lietotājs; Pēc tam drukātajā paziņojumā ir rakstīts:
Šobrīd mybatis neizmanto iepriekš kompilētus paziņojumus, tas vispirms sašūs virknes un pēc tam veiks kompilāciju, kas ir tieši tā, kā SQL injekcija stājas spēkā.
Tāpēc, rakstot mybatis kartēšanas paziņojumus, mēģiniet izmantot formātu "#{xxx}". Ja jums ir jāizmanto tādi parametri kā "${xxx}", tie ir manuāli jāfiltrē, lai novērstu SQL injekcijas uzbrukumus.
|