Isfarë është injektimi SQL dhe si të parandalohet në aplikimet PHP?

Kështu që ju mendoni se baza e të dhënave tuaja SQL është performuese dhe e sigurt nga shkatërrimi i menjëhershëm? Epo, injeksioni SQL nuk pajtohet!


Po, është shkatërrim i menjëhershëm për të cilin po flasim, sepse nuk dua ta hap këtë artikull me terminologjinë e zakonshme të çalë të “shtrëngimit të sigurisë” dhe “parandalimit të hyrjes me qëllim të keq”. Injeksioni SQL është një mashtrim kaq i vjetër në libër që të gjithë, çdo zhvillues, e dinë shumë mirë për këtë dhe është i vetëdijshëm se si ta parandalojnë atë. Me përjashtim të asaj kohe të çuditshme kur ato rrëshqasin, dhe rezultatet nuk mund të jenë asgjë më katastrofale.

Nëse tashmë e dini se çfarë është SQL Injection, mos ngurroni të kaloni në gjysmën e fundit të artikullit. Por për ata që sapo janë duke dalë në fushën e zhvillimit të uebit dhe po ëndërrojnë të marrin role më të vjetra, disa prezantime janë në rregull.

Whatfarë është injeksioni SQL?

Theelësi për të kuptuar SQL Injection është në emrin e tij: SQL + Injection. Fjala “injeksion” këtu nuk ka asnjë konotacion mjekësor, por është përdorimi i foljes “inject”. Së bashku, këto dy fjalë përcjellin idenë e vendosjes së SQL në një aplikacion në internet.

Vendosja e SQL në një aplikacion në internet. . . hmmm . . A nuk është kjo çfarë po bëjmë gjithsesi? Po, por ne nuk duam që një sulmues të drejtojë bazën e të dhënave tona. Le ta kuptojmë këtë me ndihmën e një shembulli.

Le të themi se po ndërtoni një uebfaqe tipike PHP për një dyqan lokal të tregtisë elektronike, kështu që vendosni të shtoni një formë kontakti si kjo:

Emri juaj

Mesazhi juaj

Dhe le të supozojmë se skedari send_message.php ruan gjithçka në një bazë të dhënash në mënyrë që pronarët e dyqaneve të lexojnë mesazhet e përdoruesve më vonë. Mund të ketë një kod si ky:

<?php

$ emri = $ _POST [’emri’];
$ mesazh = $ _POST [‘mesazh’];

// kontrolloni nëse ky përdorues ka tashmë një mesazh
mysqli_query ($ conn, "SELECT * nga mesazhet ku emri = emri $");

// Kodi tjetër këtu

Kështu që së pari po përpiqeni të shihni nëse ky përdorues ka tashmë një mesazh të palexuar. Kërkimi SELECT * nga mesazhet ku emri = emri $ duket mjaft i thjeshtë, apo jo?

GABUAR!

Në pafajësinë tonë, ne kemi hapur dyert për shkatërrimin e menjëhershëm të bazës së të dhënave tona. Që kjo të ndodhë, sulmuesi duhet të plotësojë këto kushte:

  • Aplikimi po ekzekutohet në një bazë të dhënash SQL (sot, pothuajse çdo aplikacion është)
  • Lidhja aktuale e bazës së të dhënave ka leje “edit” dhe “fshirje” në bazën e të dhënave
  • Emrat e tabelave të rëndësishme mund të merren me mend

Pika e tretë do të thotë që tani që sulmuesi e di se po drejton një dyqan të tregtisë elektronike, ka shumë të ngjarë që i ruan të dhënat e porosive në një tabelë të porosive. Të armatosur me të gjitha këto, gjithçka që duhet të bëjë sulmuesi është ta sigurojë këtë si emrin e tyre:

Joe; urdhra të cunguar ;? Po zoteri! Le të shohim se çfarë do të bëhet kërkesa kur të ekzekutohet nga skripti PHP:

SELECT * NGA mesazhet KU SHENJE = Joe; urdhra të cunguar;

Në rregull, pjesa e parë e pyetjes ka një gabim sintaksor (pa citime rreth “Joe”), por gjysëm-koloni detyron motorin MySQL të fillojë të interpretojë një të ri: urdhra të cunguar. Ashtu si kjo, në një ndërhyrje të vetme, e gjithë historia e rendit është zhdukur!

Tani që e dini se si funksionon SQL Injection, është koha të shikoni se si ta ndaloni atë. Dy kushtet që duhet të përmbushen për injeksion të suksesshëm të SQL janë:

  1. Skripti PHP duhet të ketë modifikim / fshirje të privilegjeve në bazën e të dhënave. Unë mendoj se kjo është e vërtetë për të gjitha aplikimet dhe nuk do të jeni në gjendje t’i bëni aplikimet tuaja vetëm të lexuara. �� Dhe me mend se çfarë, edhe nëse heqim të gjitha privilegjet, modifikimi i injektimit SQL mund të lejojë që dikush të ekzekutojë pyetje SELECT dhe të shikojë të gjithë bazën e të dhënave, përfshirë të dhëna të ndjeshme. Me fjalë të tjera, ulja e nivelit të qasjes në bazën e të dhënave nuk funksionon, dhe aplikimi juaj ka nevojë për atë sidoqoftë.
  2. Futja e përdoruesit është duke u përpunuar. E vetmja mënyrë për të funksionuar injeksioni SQL është kur pranoni të dhëna nga përdoruesit. Edhe një herë, nuk është praktike të ndaloni të gjitha inputet për aplikimin tuaj vetëm sepse shqetësoheni për injeksionin SQL.

Parandalimi i injektimit të SQL në PHP

Tani, duke pasur parasysh që lidhjet e bazës së të dhënave, pyetjet dhe inputet e përdoruesve janë pjesë e jetës, si ta parandalojmë injeksionin SQL? Për fat të mirë, është mjaft e thjeshtë, dhe ka dy mënyra për ta bërë atë: 1) sanitizoni hyrjen e përdoruesit dhe 2) përdorni deklaratat e përgatitura.

Sanitizoni hyrjen e përdoruesit

Nëse jeni duke përdorur një version të vjetër të PHP (5.5 ose më i ulët, dhe kjo ndodh shumë në pritjen e përbashkët), është e mençur të ekzekutoni të gjitha hyrjet e përdoruesit tuaj përmes një funksioni të quajtur mysql_real_escape_string (). Në thelb, ajo që bën ajo heq të gjithë karakteret e veçanta në një varg në mënyrë që ata të humbasin kuptimin e tyre kur përdoren nga baza e të dhënave.

Për shembull, nëse keni një varg si unë jam një varg, karakteri i vetëm i kuotave (‘) mund të përdoret nga një sulmues për të manipuluar pyetjen e bazës së të dhënave që krijohet dhe të shkaktojë një injeksion SQL. Drejtimi i tij përmes mysql_real_escape_string () prodhon Unë jam një varg, i cili shton një prapambetje në kuotën e vetme, duke e shpëtuar atë. Si rezultat, e tërë string tani kalohet si një varg i padëmshëm në bazën e të dhënave, në vend që të jetë në gjendje të marrë pjesë në manipulimin e pyetjeve.

Ekziston një pengesë me këtë qasje: është një teknikë me të vërtetë shumë e vjetër që shkon së bashku me format më të vjetra të qasjes në bazën e të dhënave në PHP. Ndërsa në PHP 7, ky funksion nuk ekziston më, gjë që na çon në zgjidhjen tonë të rradhës.

Përdorni deklarata të përgatitura

Deklaratat e përgatitura janë një mënyrë për t’i bërë pyetjet e bazës së të dhënave më të sigurt dhe të besueshme. Ideja është që në vend që të dërgojmë pyetjen e papërpunuar në bazën e të dhënave, së pari i tregojmë bazës së të dhënave strukturën e pyetjes që do të dërgojmë. Kjo është ajo që nënkuptojmë duke “përgatitur” një deklaratë. Pasi të përgatitet një deklaratë, ne i kalojmë informacionet si inpute të parametruara, në mënyrë që baza e të dhënave të mund “të mbushë boshllëqet” duke futur inputet në strukturën e pyetjes që kemi dërguar më parë. Kjo heq çdo fuqi të veçantë që inputet mund të kenë, duke bërë që ato të trajtohen si ndryshore të thjeshta (ose ngarkesa, nëse dëshironi) në të gjithë procesin. Ja si duken deklaratat e përgatitura:

<?php
$ servername $ = "localhost";
$ emri i përdoruesit = "Emri i përdoruesit";
fjalëkalim $ = "fjalëkalim";
$ dbname = "myDB";

// Krijoni lidhje
$ conn = mysqli i ri ($ servername $, $ username, $ fjalëkalim, $ dbname);

// Kontrolloni lidhjen
nëse ($ lidh->lidh_error) {
vdesin ("Lidhja dështoi: " . $ Conn->connect_error);
}

// përgatit dhe lidh
$ stmt = $ lidh->përgatitur ("INSERT N My MyGuests (emri, mbiemri, email) VLERAT (?,?,??)");
$ stmt->bind_param ("sss", $ emrin e parë, $ mbiemrin, $ email);

// vendosni parametrat dhe ekzekutoni
$ emri = "nevojtore";
mbiemri $ = "drenushë";
$ email = "[Email mbrojtur]";
$ stmt->ekzekutuar ();

$ emri = "mary";
mbiemri $ = "Moe";
$ email = "[Email mbrojtur]";
$ stmt->ekzekutuar ();

$ emri = "Julie";
mbiemri $ = "Dooley";
$ email = "[Email mbrojtur]";
$ stmt->ekzekutuar ();

jehonë "Regjistrime të reja të krijuara me sukses";

$ stmt->mbyllë ();
$ Conn->mbyllë ();
?>

Unë e di se procesi tingëllon panevojshëm i ndërlikuar nëse jeni i ri për të përgatitur deklarata, por koncepti ia vlen të përpiqet. këtu është një prezantim i këndshëm për të.

Për ata që janë tashmë të njohur me shtrirjen e PHP të PHP dhe e përdorin atë për të krijuar deklarata të përgatitura, kam një këshillë të vogël.

Paralajmërim: Kini kujdes kur vendosni PDO

Kur përdorim PDO për qasje në bazën e të dhënave, ne mund të thithemi në një sens të rremë sigurie. “Ah, mirë, unë jam duke përdorur PDO. Tani nuk kam nevojë të mendoj për asgjë tjetër “- kështu shkon përgjithësisht mendimi ynë. Shtë e vërtetë që PDO (ose deklaratat e përgatitura MySQLi) është e mjaftueshme për të parandaluar të gjitha llojet e sulmeve injektuese SQL, por duhet të jeni të kujdesshëm gjatë vendosjes së tij. Shtë e zakonshme të thjesht kopjoni-ngjisni kodin nga mësimet mësimore ose nga projektet tuaja të mëparshme dhe të vazhdoni më tej, por kjo cilësim mund të zhbëjë gjithçka:

$ dbConnection->setAttribute (PDO :: ATTR_EMULATE_PREPARES, e vërtetë);

Ajo që bën kjo cilësim është t’i thuash PDO-së të imitojë deklarata të përgatitura sesa të përdorë në të vërtetë tiparin e deklaratave të përgatitura të bazës së të dhënave. Si pasojë, PHP dërgon vargje të thjeshta të pyetjeve në bazën e të dhënave edhe nëse kodi juaj duket sikur po krijon deklarata të përgatitura dhe vendos parametra dhe e gjithë kjo. Me fjalë të tjera, ju jeni po aq e ndjeshëm ndaj injeksionit SQL si më parë. ��

Zgjidhja është e thjeshtë: sigurohuni që kjo simulim të jetë e rremë.

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

Tani skripti PHP është i detyruar të përdorë deklarata të përgatitura në një bazë të dhënash, duke parandaluar të gjitha llojet e injektimit SQL.

Parandalimi i përdorimit të WAF

A e dini se gjithashtu mund të mbroni aplikacionet në internet nga injeksioni SQL duke përdorur WAF (firewall i aplikacionit në internet)?

Epo, jo vetëm injeksioni SQL, por shumë të tjera 7 shtresa të dobëta si skriptimi ndër-site, vërtetimi i thyer, falsifikimi ndër-site, ekspozimi i të dhënave, etj. Ose mund të përdorni vetë-pritur si Mod Security ose bazuar në cloud si më poshtë.

Injeksione SQL dhe kornizat moderne PHP

Injeksioni SQL është kaq i zakonshëm, kaq i lehtë, aq zhgënjyes dhe aq i rrezikshëm sa të gjitha kornizat moderne të internetit të PHP ndërtohen me kundërmasa. Në WordPress, për shembull, kemi $ wpdb->përgatisni funksionin (), ndërsa nëse përdorni një kornizë MVC, ajo bën të gjitha punët e pista për ju dhe nuk do të duhet të mendoni për parandalimin e injeksionit SQL. Littleshtë pak e bezdisshme që në WordPress duhet të përgatisni deklarata në mënyrë të qartë, por hej, është WordPress për të cilën po flasim. ��

Sidoqoftë, mendimi im është, raca moderne e zhvilluesve të uebit nuk duhet të mendojnë për injeksion SQL, dhe si rezultat, ata as nuk janë në dijeni të mundësisë. Si i tillë, edhe nëse ata e lënë një prapavijë të hapur në aplikimin e tyre (mbase është një parametër $ _GET i pyetjes dhe zakonet e vjetra të pushkatimit nga një goditje e ndyrë në pyetje), rezultatet mund të jenë katastrofike. Prandaj është gjithmonë më mirë të marrësh kohën për të zhyten më thellë në themelet.

përfundim

Injeksioni SQL është një sulm shumë i keq ndaj një aplikacioni në internet, por shmanget lehtësisht. Siç e pamë në këtë artikull, të jesh i kujdesshëm gjatë përpunimit të hyrjes së përdoruesit (nga rruga, SQL Injection nuk është kërcënimi i vetëm që sjell trajtimi i hyrjes së përdoruesit) dhe kërkimi i bazës së të dhënave është gjithçka që i përket. Thënë kështu, ne nuk jemi gjithmonë duke punuar në sigurinë e një kornize në internet, kështu që është më mirë të jemi të vetëdijshëm për këtë lloj sulmi dhe të mos biem për të.

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