SQL INJECTION ATTACK PREVENTION I PHP / CODE EXAMPLES

etter flere år med penetrasjonstesting og arbeid med utviklingsteam for å sikre sine systemer, har jeg lagt merke til at det ikke var noe komplett blogginnlegg som gir en detaljert forklaring på hvordan du kan forhindre SQL injection-angrep i alle de mest populære webapplikasjonsutviklingsspråkene og rammene. Derfor bestemte jeg meg for å skrive en serie med flere innlegg for å gjøre den til den mest komplette veiledningen for å forhindre SQL-injeksjon.

denne guiden er en åpen serie med innlegg, og dette er det første innlegget. Hvis du vil at jeg skal legge til noen teknologi, kan du bare kommentere nedenfor, og jeg vil være veldig glad for å forklare SQL injeksjon forebygging for at teknologi. Denne veiledningen vil analysere følgende teknologier:

  • PHP
    • Laravel
    • Symfony
    • CodeIgniter
    • CakePHP
    • FuelPHP
    • Zend
  • JEE
    • JDBC
    • JPA
  • ASP.NET
    • ADO.NET
    • ADO.NETTO Dopper
    • NHibernate

Dette første innlegget vil fokusere på PHP-språket og alle dets rammer. Flere artikler vil følge for å håndtere de andre oppførte teknologiene.

for de som ikke vet HVA SOM ER SQL injection attack, la meg gjøre en liten introduksjon for å forklare dette for dem. SQL-injeksjonsangrep skjer når en dårlig bruker prøver å injisere en ondsinnet SQL-forespørsel i en legitim forespørsel. VIRKNINGEN AV SQL-injeksjonsangrep varierer fra en situasjon til en annen, avhengig av flere elementer relatert til appmiljøet, og det kan gå fra så “enkelt” som informasjonslekkasje til full serverkontroll. Jeg vil ikke gå dypere inn i måten en angriper kan utnytte dette sikkerhetsproblemet eller hvordan vi kan oppdage det i blackbox-tester, da dette ikke er målet med dette innlegget. Hva vi vil se er hvordan å oppdage det i kildekoden og hvordan å fikse det.

hvordan forhindre SQL-injeksjon angrep i En Ren PHP kildekode ?

La oss starte vår reise med en av de eldste OG populære utviklingsteknologi PHP uten noen rammer. Nå er det første du må gjøre å vite hvordan en sårbar kildekodelinje ser ut til å kunne identifisere sårbarheten.

her er et eksempel på en godkjenningsforespørsel:

$request = "SELECT * FROM users WHERE username=". $_POST ." AND password = ". $_POST;
$result = $mysqli->query($request);

Nå, hvis du tar en nærmere titt på forespørselen, vil du legge merke til at brukerparametrene $_POST og $_POST injiseres direkte i SQL-forespørselen uten filtrering. Gjør du det, gjør denne kodelinjen sårbar FOR SQL-injeksjon.

for å fikse dette sikkerhetsproblemet må du filtrere dataene før du bruker dem i sql-forespørselen. For å gjøre dette er den beste løsningen å bruke de forberedte uttalelsene. Her er et eksempel på hvordan du kan bruke de forberedte uttalelsene til å fikse dette sikkerhetsproblemet:

$conn = new mysqli($servername, $username, $password, $dbname);
$stmt = $conn->prepare("SELECT * FROM users WHERE username=? AND password=?");
$stmt->bind_param($username, $password);
$stmt->execute();

God praksis

du har mulighet til å ikke bruke bind_param () – funksjonen her er et eksempel på hvordan du gjør dette :

$conn = new mysqli($servername, $username, $password, $dbname);
$stmt = $conn->prepare("SELECT * FROM users WHERE username=:username AND password=:password");
$stmt-> execute(array('username'=>$_POST,'password'=>$_POST));

Etter år med å analysere kildekoder … jeg har oppdaget en interessant feil som mange utviklere gjør mens fikse dette sikkerhetsproblemet. Ta en titt på følgende eksempel:

$stmt = $conn->prepare("SELECT * FROM users WHERE username=".$_POST." AND password=".$_POST);

hvis du ser på dette eksemplet, vil du se at vi bruker de forberedte uttalelsene. Parametrene injiseres imidlertid direkte i SQL-forespørselen. Dette er en veldig vanlig feil som utviklere gjør, og gjør koden sårbar FOR SQL-injeksjon, selv om vi bruker de forberedte uttalelsene.

ideen bak de forberedte uttalelsene er å filtrere parametrene før du injiserer DEM i SQL-forespørselen … hold dette i tankene dine.

Veldig Viktig merknad:

PHP tilbyr noen andre funksjoner for å filtrere SQL-forespørsler og forhindre SQL-injeksjon, men noen av dem er ikke effektive. Mysql_real_escape_string () – funksjonen er for eksempel en AV DE mest kjente PHP-funksjonene for å forhindre SQL-injeksjon. Dessverre er denne funksjonen veldig effektiv. Ved å bruke denne funksjonen vil MySQL-biblioteket legge til en backslash til følgende tegn: NULL, \ x00, \ n, \ r,\,’, ” og \ x1a. Men for en situasjon som denne :

$id = mysql_real_escape_string("1 OR 1=1");
$request = "SELECT * FROM users WHERE id = $id";

i rød farge er hva en dårlig bruker vil sende deg

mysql_real_escape_string() vil ikke beskytte deg mot slike angrep.

Derfor anbefaler jeg alltid å bruke de forberedte uttalelsene i stedet for denne funksjonen.

hvordan forhindre SQL-injeksjon angrep I Laravel rammeverk ?

Nå som VI har sett SQL-injeksjonsangrepet mot En Ren PHP-kode, er det nå på tide å se hvordan vi kan fikse sårbarheten i et rammebasert webprogram. Før vi begynner å snakke om dette, la meg først gi deg en liten beskrivelse Av Laravel-rammen.

Laravel Er en åpen kildekode web rammeverk skrevet I PHP respektere modell-view-controller prinsippet og helt utviklet i objektorientert programmering.

Eksempel 1

her er et eksempel på en sårbar SQL-forespørsel i en laravel :

$user = DB::select('select * from users where username='. $request->post('username').' AND password='. $request->post('password'));

Laravel framework tilbyr noen fantastiske funksjoner for å hjelpe utviklere å sikre SQL-forespørselen mot ondsinnede injeksjoner. Dessverre, DE fleste AV SQL-injeksjon sårbarheter som jeg oppdager i slike programmer er relatert til misbruk Av Laravel funksjoner.

la oss analysere det forrige eksemplet, I Henhold Til laravel-dokumentasjonen KAN DB:: select-funksjonen motta to parametere. DEN første ER SQL-forespørselen, og den andre er parametrene. Så for å filtrere parametrene FOR SQL-injeksjon må du sette inn parametrene i forespørselen ved hjelp av den andre parameteren akkurat som dette eksemplet:

$ user = DB:: select (‘velg * fra brukere hvor brukernavn=? Passord=?’, );

Eksempel 2

Laravel har flere måter å kommunisere med databasen i dette eksemplet vil du se at laravel tvinge utvikleren til å bruke noen funksjoner som automatisk filtrerer brukerdataene, som følgende eksempel:

Users::where('username', $request->get('username'))->orderBy($request->get('orderby'))->get();

Denne funksjonen skal sikres mot SQL-injeksjon, og de er, det eneste problemet er på orderBy() funksjonsnivå. Ifølge laravel-dokumentasjonen filtrerer denne funksjonen ikke brukerdataene, slik at ET SQL-injeksjonsangrep fortsatt er mulig gjennom denne funksjonen.

det beste å gjøre er ikke å gi brukeren muligheten til å kontrollere tabellnavnet, Men hvis dette er noe uunngåelig, må du bruke en hvit liste for å validere brukerdataene før du setter den inn i den funksjonen.

hvordan forhindre SQL-injeksjon angrep I Symfony ?

La oss se et annet KJENT PHP-rammeverk som tilbyr et sett med gjenbrukbare PHP-komponenter for å akselerere PHP apps utvikling. Symfony brukes også av noen av de mest kjente web CMS som Drupal Og Magento.

Symfony er et av de sikreste rammene du kan jobbe med, det tilbyr et bredt antall funksjoner for å skrive en sikker kode. Men hvis disse funksjonene ikke er godt brukt, får du en sårbar kode. Så her er et eksempel på en sårbar kode:

$entityManager = $this->getEntityManager();
$query = $entityManager->createQuery('SELECT p
FROM App\Entity\Product p
WHERE p.price > '. $request->query->get('price')
);

la oss nå analysere denne sårbare koden. Ifølge Symfony-dokumentasjonen er createQuery () en funksjon som som standard bruker de forberedte setningene. Så, objektet som kommer fra en slik funksjon gir deg tilgang til setParameter () – funksjonen. Denne filtrerer alle brukerdata for å unngå EN SQL-injeksjon. Her er et eksempel på hvordan du bruker det :

$entityManager = $this->getEntityManager();
$query = $entityManager->createQuery('SELECT p
FROM App\Entity\Product p
WHERE p.price > :price
ORDER BY p.price ASC'
)->setParameter('price', $price);

hvordan forhindre SQL-injeksjonsangrep I Codeigniter ?

CodeIgniter En av de kraftigste, lette og populære PHP rammeverk med en svært liten plass. Den ble bygget for utviklere som trenger en enkel og elegant verktøykasse for å lage fullverdige webapplikasjoner. Som Symfony og Laravel, Codeigniter kommer også med noen sikkerhetssystemer for å hjelpe utviklere å lage tryggere apps.

men også Med Codeigniter gjør noen utviklere den samme feilen og injiserer brukerdataene uten filtrering. Her er et eksempel på slike feil som fører TIL ET SQL-injeksjonsangrep:

$query = 'SELECT * FROM users WHERE username = '. $this-> input->post('username'). ' AND password= '. $this-> input->post('password');
$this->db->query($query);

nå for å fikse dette problemet, må du ta en titt På Codeigniter-dokumentasjonen. I følge det tar spørringen () – funksjonen to parametere. Den første er sql-spørringen, og den andre er parametrene du vil binde.

Eksempel 1

som standard filtrerer denne funksjonen alle de bindede parameterne for å forhindre SQL-injeksjoner. Her er et eksempel på riktig måte å bruke denne funksjonen på:

$query = 'SELECT * FROM users WHERE username = ? AND password = ? ';
$this->db->query($query, array($this->input->post('username'), $this-> input-> post('password')));

Eksempel 2:

Codeigniter gi en annen måte å utføre SQL forespørsel vil hindre SQL-injeksjoner. Her er et eksempel på Bruk Av Aktiv Postklasse for å forhindre SQL-injeksjoner:

$this->db->get_where('users',array('username'=>$this->input->post('username') ,'password' => $this->input->post('password')));

get_where () – funksjonen finnes ikke lenger i versjon 4 Av Codeigniter.

Notat 1

Codeigniter tilbyr ogsa en funksjon som ser ut som, mysql_real_escape_string () funksjon kalt escape (). Men som jeg først sa mysql_real_escape_string () kan omgås i noen tilfeller, og du må unngå å bruke den. Det faktum at escape () – funksjonen gjør akkurat det samme, da ville det være mulig å omgå det også. Derfor oppfordrer jeg ikke utviklere til å bruke escape () – funksjonen.

Notat 2

hvordan forhindre SQL-injeksjonsangrep I CakePHP ?

CakePHP Er en rask utvikling rammeverk FOR PHP som bruker kjente designmønstre som Associative Data Mapping, Front Controller, Og MVC. CakePHP tilbyr en haug med innebygd komponent for å lette utviklingen av webapplikasjoner og vil gjøre dem sikrere.

CakePHP-apper er imidlertid også sårbare for SQL-injeksjoner hvis Den ikke er godt brukt. Her er et eksempel på en sårbar kode FOR SQL-injeksjonsangrep i dette rammeverket:

$results = $connection-> execute('SELECT * FROM users WHERE username = '. $this->request->getParam('username').' AND password='. $this->request->getParam('password'))->fetchAll('assoc');

utfør () – funksjonen bruker som standard de forberedte setningene. Det forrige eksemplet er imidlertid fortsatt sårbart FOR SQL-injeksjonsangrep, da brukerdataene settes inn direkte i en legitim sql-forespørsel. Her er et eksempel på den riktige måten å bruke denne funksjonen på:

$results = $connection->execute('SELECT * FROM users WHERE username = :username AND password=:password', )->fetchAll('assoc');

CakePHP framework tilbyr også et system kalt Query Builder, som tvinger brukerdatafiltrering for å forhindre SQL-injeksjonsangrep. Ifølge cakephp-dokumentasjonen, Under dekslene, Bruker Spørringsbyggeren de forberedte uttalelsene.

her er et eksempel på hvordan du kan bruke et slikt system på riktig måte:

use Cake\ORM\Locator\LocatorAwareTrait;
$users = $this->getTableLocator()->get('users');
// Start a new query.
$query = $users->find();
$query->where();

hvordan forhindre SQL-injeksjonsangrep I FuelPHP ?

FuelPHP Er en AV DE nyeste PHP rammeverk som ble født basert på de beste ideene til hvert rammeverk i markedet. DEN ble utviklet MED PHP 5 og er fullt objektorientert. I FuelPHP var sikkerhet først og fremst bekymret, noe som presset bidragsyterne til å implementere mange sikkerhetsmekanismer for å filtrere brukerdata. SQL-injeksjon angriper en av grunnene til å implementere slike mekanismer I FuelPHP.

men selv med en så kraftig rammeverk, en enkel misbruk av disse mekanismene sette hele koden i fare for EN SQL-injeksjon angrep. Her er et eksempel på en slik kodefeil:

$query = "SELECT * FROM article WHERE id = ". Input::get('id');
$result = DB::query($query)->execute();

For å fikse dette, er det også to teknikker som de andre rammene. Den første er å faktisk bruke spørringen () – funksjonen riktig, ved å binde parametrene som følgende eksempel :

$query = "SELECT * FROM article WHERE id = :id"; // our query
$result = DB::query($query)->bind('id', Input::get('id'))->execute();

Den andre løsningen er Å bruke orm mekanisme implementert I FuelPHP rammeverk for å kommunisere med databasen. Her er et eksempel på hvordan du bruker det:

$user = DB::select()->from('article')->where('id', Input::get('id'))->execute();

hvordan forhindre SQL-injeksjonsangrep i zend framework ?

Zend framework (endret Til Laminas Prosjekt) er en av DE mest kjente rammeverket I VERDEN AV PHP. Den ble utviklet med tanke på ytelsesjustering, noe som forklarer hvorfor hver ny versjon er mye raskere enn den gamle. Zend ble også utviklet med de beste sikkerhetspraksis, som presset utviklerne til å implementere flere sikkerhetsmekanismer for å håndtere kjente cybertrusler.

Noen av disse mekanismene ble implementert for å håndtere SQL-injeksjonsangrepene. Men som alltid fører misbruk av disse mekanismene til en sårbar kode. I denne delen av artikkelen skal jeg vise et eksempel på en slik feil:

$adapter->query('SELECT * FROM `article` WHERE `id` = '. $this->getRequest()->getPost('id'));

slik løser du dette sikkerhetsproblemet:

$adapter->query('SELECT * FROM `article` WHERE `id` = ?', );

Leave a Reply