Što je SQL ubrizgavanje i kako spriječiti u PHP aplikacijama?

Dakle, mislite da je vaša SQL baza podataka učinkovita i sigurna od trenutnog uništenja? Pa, SQL ubrizgavanje se ne slaže!


Da, o mom trenutnom uništenju govorimo, jer ne želim ovaj članak otvoriti uobičajenom hromom terminologijom “pooštravanja sigurnosti” i “sprečavanja zlonamjernog pristupa.” SQL Injection je toliko stari trik u knjizi da svi, svaki programer, znaju vrlo dobro i dobro su svjesni kako ga spriječiti. Osim onog neobičnog trenutka kada se okliznu, a rezultati ne mogu biti ništa katastrofalni.

Ako već znate što je SQL ubrizgavanje, slobodno prijeđite na drugu polovicu članka. Ali za one koji se tek pojavljuju u području razvoja web stranica i sanjaju o starijim ulogama, na redu je neko upoznavanje.

Što je SQL ubrizgavanje?

Ključ razumijevanja SQL injekcije je u nazivu: SQL + ubrizgavanje. Riječ “injekcija” ovdje nema medicinske konotacije, već je upotreba glagola “ubrizgati”. Ove dvije riječi zajedno prenose ideju stavljanja SQL-a u web aplikaciju.

Stavljanje SQL-a u web aplikaciju. , , hmmm. , , Nije li to uopće ono što radimo? Da, ali ne želimo da napadač pokreće našu bazu podataka. Shvatimo to pomoću primjera.

Recimo da gradite tipičnu PHP web lokaciju za lokalnu trgovinu e-trgovine, pa odlučite dodati kontakt obrazac poput ovog:

Tvoje ime

Tvoja poruka

A pretpostavimo da datoteka send_message.php pohranjuje sve u bazu podataka kako bi vlasnici trgovina mogli kasnije čitati korisničke poruke. Može imati ovako šifru:

<?pHP

$ name = $ _POST [‘ime’];
$ message = $ _POST [‘poruka’];

// provjerite ima li ovaj korisnik već poruku
mysqli_query ($ conn, "ODABIR * iz poruka u kojima je ime = $ ime");

// Ostali kod ovdje

Stoga prvo pokušavate vidjeti ima li ovaj korisnik nepročitanu poruku. Upit SELECT * iz poruka u kojima se name = $ name čini dovoljno jednostavnim, točno?

POGREŠNO!

Svoju nevinost otvorili smo vrata trenutnom uništavanju naše baze podataka. Da bi se to dogodilo, napadač mora imati sljedeće uvjete:

  • Aplikacija se izvodi na SQL bazi podataka (danas je gotovo svaka aplikacija)
  • Trenutna veza s bazom podataka ima dopuštenja za uređivanje i brisanje u bazi podataka
  • Imena važnih tablica mogu se nagađati

Treća točka znači da sada, kada napadač zna da imate trgovinu e-trgovine, vrlo je vjerojatno da podatke o narudžbi pohranjujete u tablicu naloga. Naoružani svim tim napadač, sve što napadač treba učiniti je pružiti to kao svoje ime:

Joe; skraćivati ​​narudžbe ;? Da gospodine! Pogledajmo kakav će upit postati kada ga izvrši skripta PHP:

ODABIR * OD poruka GDJE ime = Joe; skraćivati ​​naloge;

U redu, prvi dio upita ima sintaksičku grešku (bez navodnika oko “Joea”), ali zarez dvotočke tjera MySQL engine da počne interpretirati novi: skraćivati ​​naredbe. Baš tako, u jednom jedinom naletu nestaje čitava povijest narudžbi!

Sada kada znate kako funkcionira SQL injekcija, vrijeme je da pogledate kako je zaustaviti. Dva uvjeta koja moraju biti ispunjena za uspješnu injekciju SQL-a su:

  1. PHP skripta trebala bi mijenjati / brisati povlastice u bazi podataka. Mislim da to vrijedi za sve aplikacije i nećete moći učiniti da aplikacije budu samo za čitanje. �� I pogodite što, čak i ako uklonimo sve povlastice za modificiranje, SQL injekcija još uvijek može dopustiti nekome da izvodi SELECT upite i pregleda svu bazu podataka, uključujući osjetljive podatke. Drugim riječima, smanjivanje razine pristupa bazi podataka ne radi i vašoj aplikaciji to ionako treba.
  2. Obrađuje se korisnički unos. Jedini način na koji SQL injekcija može funkcionirati je kada prihvaćate podatke od korisnika. Još jednom, nije praktično zaustaviti sve unose za vašu aplikaciju samo zato što ste zabrinuti zbog ubrizgavanja SQL-a.

Sprječavanje ubrizgavanja SQL-a u PHP

Sada, s obzirom da su veze baze podataka, upiti i unosi korisnika dio života, kako spriječiti ubrizgavanje SQL-a? Srećom, to je prilično jednostavno i postoje dva načina za to: 1) pročišćavanje korisničkog unosa i 2) korištenje pripremljenih izjava.

Sanitizirajte unos korisnika

Ako koristite stariju verziju PHP-a (5.5 ili starije, a to se puno događa na zajedničkom hostingu), pametno je pokrenuti sve svoje korisničke unose putem funkcije zvane mysql_real_escape_string (). U osnovi, ono što čini uklanja sve posebne znakove u nizu, tako da gube svoje značenje kada ih koristi baza podataka.

Na primjer, ako imate niz poput “Ja sam niz”, napadač može upotrijebiti znak jednog citata (‘) za manipuliranje upitom u bazu podataka koji se stvara i uzrokovati ubrizgavanje SQL-a. Ako ga pokrećem kroz mysql_real_escape_string (), proizvedem niz, koji dodaje crte kose crte unatrag i izostaje. Kao rezultat toga, cijeli niz sada se prenosi kao bezopasan niz u bazu podataka, umjesto da može sudjelovati u manipulaciji s upitima..

Postoji jedan nedostatak ovog pristupa: to je stvarno, stvarno stara tehnika koja ide zajedno sa starijim oblicima pristupa bazi podataka u PHP-u. Kao što je to slučaj sa PHP-om 7, ova funkcija više ne postoji, što nas dovodi do sljedećeg rješenja.

Koristite pripremljene izjave

Pripremljene izjave način su za siguran i pouzdan način upiti u bazu podataka. Ideja je da umjesto slanja neobrađenog upita u bazu, prvo kažemo bazi podataka strukturu upita koju ćemo poslati. To mislimo pod “pripremom” izjave. Jednom kada je izjava pripremljena, podatke prosljeđujemo kao parametrizirane ulaze kako bi baza podataka mogla „popuniti praznine“ dodavanjem ulaza u strukturu upita koju smo prethodno poslali. Ovo oduzima svaku posebnu snagu koju ulaz može imati, uzrokujući da se oni tijekom cijelog postupka tretiraju kao puke varijable (ili korisni opterećenja). Evo kako izgledaju pripremljene izjave:

<?pHP
$ servername = "localhost";
$ username = "Korisničko ime";
$ lozinka = "lozinka";
$ dbname = "MyDB";

// Stvori vezu
$ conn = novi mysqli ($ servername, $ username, $ password, $ dbname);

// Provjerite vezu
ako ($ conn->connect_error) {
umrijeti("Veza nije uspjela: " . $ conn->connect_error);
}

// pripremiti i vezati
$ stmt = $ conn->pripremiti("ULAZITE U MyGuestove (ime, prezime, e-pošta) VRIJEDNOSTI (?,?,?)");
$ stmt->bind_param ("sss", $ ime, $ prezime, $ e-pošta);

// postaviti parametre i izvršiti
$ ime = "Ivan";
$ prezime = "srna";
$ email = "[E zaštićeni]";
$ stmt->izvršiti();

$ ime = "Marija";
$ prezime = "Moe";
$ email = "[E zaštićeni]";
$ stmt->izvršiti();

$ ime = "Julie";
$ prezime = "Dooley";
$ email = "[E zaštićeni]";
$ stmt->izvršiti();

jeka "Novi zapisi uspješno su stvoreni";

$ stmt->Zatvoriti();
$ conn->Zatvoriti();
?>

Znam da postupak zvuči nepotrebno složeno ako ste novi u pripremljenim izjavama, ali koncept je vrijedan truda. Evo lijep uvod u to.

Za one koji su već upoznati sa PHP-ovim proširenjem PDO-a i koriste ga za izradu pripremljenih izjava, imam mali savjet..

Upozorenje: Budite oprezni prilikom postavljanja PDO-a

Kada koristimo PDO za pristup bazi podataka, možemo se usisati u lažni osjećaj sigurnosti. “Ah, dobro, koristim PDO. Sada ne trebam razmišljati ni o čemu drugom “- tako ide obično naše mišljenje. Točno je da je PDO (ili MySQLi pripremljeni izrazi) dovoljan da spriječe sve vrste napada SQL ubrizgavanja, ali morate biti oprezni prilikom postavljanja. Uobičajeno je samo kopirati i zalijepiti kôd s tutorijala ili iz ranijih projekata i krenuti dalje, ali ova postavka može poništiti sve:

$ dbConnection->setAttribute (PDO :: ATTR_EMULATE_PREPARES, istina);

Ono što ova postavka čini jest reći PDO-u da oponaša pripremljene izjave, a ne da zapravo koristi značajku pripremljenih izjava u bazi podataka. Prema tome, PHP šalje jednostavne nizove upita u bazu podataka, čak i ako vaš kôd izgleda kao da stvara pripremljene izjave i postavlja parametre i sve to. Drugim riječima, podložni ste SQL injekciji kao i prije. ��

Rješenje je jednostavno: provjerite je li ova emulacija postavljena na netočno.

$ dbConnection->setAttribute (PDO :: ATTR_EMULATE_PREPARES, lažno);

Sada je PHP skripta prisiljena koristiti pripremljene izjave na razini baze podataka, sprječavajući sve vrste SQL ubrizgavanja.

Sprječavanje upotrebe WAF

Znate li da također možete zaštititi web aplikacije od SQL injekcije pomoću WAF (vatrozid web aplikacije)?

Pa, ne samo SQL ubrizgavanje, već i mnoge druge ranjivosti na razini 7 slojeva, kao što su skripti na više mjesta, slomljena provjera autentičnosti, krivotvorenje na više stranica, izlaganje podataka, itd. Ili možete koristiti samostalno hostirano poput Mod Security ili temeljeno na oblaku kao sljedeće.

SQL ubrizgavanje i moderni PHP okviri

SQL injekcija je toliko česta, tako lagana, tako frustrirajuća i tako opasna da se svi suvremeni PHP web okviri ugrađuju u mjere protumjere. Na primjer, u WordPressu imamo $ wpdb->pripremite () funkciju, dok ako koristite MVC okvir, on radi svu prljavu stvar za vas i ne morate čak razmišljati o sprječavanju ubrizgavanja SQL-a. Malo je neugodno da u WordPressu morate eksplicitno pripremiti izjave, ali hej, to je WordPress o kojem govorimo. ��

U svakom slučaju, moja poanta je da moderna pasmina web programera ne mora razmišljati o injekciji SQL-a, pa kao rezultat toga nisu ni svjesni te mogućnosti. Kao takvi, čak i ako u aplikaciji ostave otvoreni jedan stražnji pokrov (možda je to parametar upita $ _GET i stare navike puštanja prljavog upita), rezultati mogu biti katastrofalni. Tako je uvijek bolje izdvojiti vrijeme za zaroniti dublje u temelje.

Zaključak

SQL ubrizgavanje je vrlo gadan napad na web aplikaciju, ali je lako izbjeći. Kao što smo vidjeli u ovom članku, pažnja prilikom obrade korisničkog unosa (usput, SQL ubrizgavanje nije jedina prijetnja koju donosi rukovanje korisničkim unosom) i ispitivanje baze podataka je samo tu. To je reklo, da ne radimo uvijek na sigurnosti web okvira, zato je bolje biti svjestan ove vrste napada, a ne padati na njega.

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map