I PHP / kodeeksempler
efter flere års penetrationstest og samarbejde med udviklingshold for at sikre deres systemer, har jeg bemærket, at der ikke var noget komplet blogindlæg, der giver en detaljeret forklaring på, hvordan man forhindrer os i alle de mest populære sprog og rammer for udvikling af applikationer. Derfor besluttede jeg at skrive en række flere indlæg for at gøre det til den mest komplette guide til at forhindre injektion.
denne vejledning er en åben serie af indlæg, og dette er det første indlæg. Hvis du vil have mig til at tilføje nogen teknologi, skal du bare kommentere nedenfor, og jeg vil være meget glad for at forklare injektionsforebyggelse for den teknologi. Denne vejledning analyserer følgende teknologier:
- PHP
- Laravel
- Symfoni
- CodeIgniter
- CakePHP
- FuelPHP
- send
- JEE
- JDBC
- JPA
- ASP.NET
- ADO.NET
- ADO.NET Dopper
- NHibernate
dette første indlæg vil fokusere på PHP-sproget og alle dets rammer. Flere artikler vil følge for at beskæftige sig med de andre børsnoterede teknologier.
for dem, der ikke ved, hvad der er indsprøjtningsangreb, lad mig lave en lille introduktion for at forklare dette for dem. En dårlig bruger forsøger at injicere en ondsindet anmodning i en legitim anmodning. Virkningen af indsprøjtningsangreb adskiller sig fra en situation til en anden afhængigt af flere elementer relateret til appmiljøet, og det kan gå fra så “simpelt” som informationslækage til en fuld serverkontrol. Jeg vil ikke gå dybere ind i, hvordan en angriber kunne udnytte denne sårbarhed, eller hvordan vi kan opdage den i sortbokstest, da dette ikke er målet med dette indlæg. Hvad vi vil se, er, hvordan man opdager det i kildekoden, og hvordan man løser det.
Sådan forhindrer du indsprøjtningsangreb i en ren PHP-kildekode ?
lad os starte vores rejse med en af de ældste og populære udviklingsteknologi PHP uden nogen rammer. Nu er den første ting at gøre at vide, hvordan en sårbar kildekodelinje ser ud for at kunne identificere sårbarheden.
her er et eksempel på en anmodning om godkendelse:
$request = "SELECT * FROM users WHERE username=". $_POST ." AND password = ". $_POST;
$result = $mysqli->query($request);
nu, hvis du kigger nærmere på anmodningen, vil du bemærke, at brugerparametrene $_POST og $_POST injiceres direkte i anmodningen uden nogen filtrering. Dette gør denne kodelinje sårbar over for indsprøjtning.
for at løse denne sårbarhed skal du filtrere dataene, før du bruger dem i anmodningen. For at gøre dette er den bedste løsning at bruge de forberedte udsagn. Her er et eksempel på, hvordan du kan bruge de forberedte udsagn til at løse denne sårbarhed:
$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 mulighed for ikke at bruge bind_param () – funktionen her er et eksempel på, hvordan du gø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));
jeg har opdaget en interessant fejl, som mange udviklere gør, mens de løser denne sårbarhed. Se på følgende eksempel:
$stmt = $conn->prepare("SELECT * FROM users WHERE username=".$_POST." AND password=".$_POST);
hvis du ser på dette eksempel, vil du se, at vi bruger de forberedte udsagn. Parametrene injiceres dog direkte i anmodningen. Dette er en meget almindelig fejl, som udviklere gør, og gør koden sårbar over for indsprøjtning, selvom vi bruger de forberedte udsagn.
ideen bag de forberedte udsagn er at filtrere parametrene, før du injicerer dem i anmodningen … husk dette.
meget vigtig note:
PHP tilbyder nogle andre funktioner til at filtrere anmodninger og forhindre indsprøjtning, men nogle af dem er ikke effektive. Funktionen mysl_real_escape_string() er for eksempel en af de mest kendte PHP-funktioner for at forhindre injektion af OKL. Desværre er denne funktion virkelig effektiv. Ved at bruge denne funktion tilføjer biblioteket et Omvendt skråstreg til følgende tegn: NULL, \ H00, \ n, \ r,\,’, ” og \ H1A. men for en situation som denne :
$id = mysql_real_escape_string("1 OR 1=1");
$request = "SELECT * FROM users WHERE id = $id";
i rød farve er, hvad en dårlig bruger vil sende dig
mysk_real_escape_string() vil ikke beskytte dig mod et sådant angreb.
derfor anbefaler jeg altid at bruge de forberedte udsagn i stedet for denne funktion.
hvordan man forhindrer indsprøjtningsangreb i Laravel-rammer ?
nu hvor vi har set indsprøjtningsangrebet mod en ren PHP-kode, er det nu tid til at se, hvordan vi kan løse sårbarheden i en rammebaseret internetapplikation. Før vi begynder at tale om dette, lad mig først give dig en lille beskrivelse af Laravel-rammen.
Laravel er en open source-ramme skrevet i PHP, der respekterer model-Vis-controller-princippet og er helt udviklet i objektorienteret programmering.
eksempel 1
her er et eksempel på en sårbar KVL-anmodning i en laravel :
$user = DB::select('select * from users where username='. $request->post('username').' AND password='. $request->post('password'));
Laravel-rammen tilbyder nogle fantastiske funktioner, der hjælper udviklere med at sikre anmodningen mod ondsindede injektioner. Desværre er de fleste af de sårbarheder, som jeg opdager i sådanne apps, relateret til misbrug af Laravel-funktioner.
lad os analysere det foregående eksempel, ifølge Laravel-dokumentation kunne DB::select-funktionen modtage to parametre. Den første er anmodningen, og den anden er parametrene. Så for at filtrere parametrene for indsprøjtning skal du indsætte parametrene i anmodningen ved hjælp af den anden parameter ligesom dette eksempel :
$user = DB::vælg(‘Vælg * fra brugere, hvor brugernavn=? Og adgangskode=?’, );
eksempel 2
Laravel har flere måder at kommunikere med databasen i dette eksempel vil du se, at laravel tvinger udvikleren til at bruge nogle funktioner, der automatisk filtrerer brugerdataene, som følgende eksempel:
Users::where('username', $request->get('username'))->orderBy($request->get('orderby'))->get();
denne funktion formodes at være sikret mod indsprøjtning, og de er, det eneste problem er på orderBy() funktionsniveau. Ifølge Laravel-dokumentationen filtrerer denne funktion ikke brugerdataene, så et indsprøjtningsangreb er stadig muligt gennem denne funktion.
den bedste ting at gøre er ikke at give brugeren mulighed for at kontrollere tabelnavnet, men hvis dette er noget uundgåeligt, skal du bruge en hvid liste til at validere brugerdataene, før du indsætter dem i denne funktion.
hvordan man forhindrer indsprøjtningsangreb i Symfony ?
lad os se en anden velkendt PHP-ramme, der tilbyder et sæt genanvendelige PHP-komponenter for at fremskynde udviklingen af PHP-apps. Symfony bruges også af nogle af de mest kendte CMS-systemer som Drupal og Magento.
Symfony er en af de mest sikre rammer, du kan arbejde med, den tilbyder et bredt antal funktioner til at skrive en sikker kode. Men hvis disse funktioner ikke bruges godt, 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')
);
lad os nu analysere denne sårbare kode. I henhold til Symfony-dokumentation er createforespørgsel() en funktion, der som standard bruger de forberedte udsagn. Så objektet som følge af en sådan funktion giver dig adgang til setParameter () – funktionen. Denne filtrerer alle brugerdata for at undgå en indsprøjtning. Her er et eksempel på, hvordan man bruger 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);
Sådan forhindrer du indsprøjtningsangreb i Codeigniter ?
CodeIgniter en af de mest kraftfulde, lette og populære PHP-rammer med et meget lille fodaftryk. Det blev bygget til udviklere, der har brug for et enkelt og elegant værktøjssæt til at oprette komplette internetapplikationer. Ligesom Symfony og Laravel leveres Codeigniter også med nogle sikkerhedssystemer, der hjælper udviklere med at skabe sikrere apps.
men også med Codeigniter gør nogle udviklere den samme fejl og injicerer brugerdataene uden nogen filtrering. Her er et eksempel på sådanne fejl, der fører til et indsprøjtningsangreb:
$query = 'SELECT * FROM users WHERE username = '. $this-> input->post('username'). ' AND password= '. $this-> input->post('password');
$this->db->query($query);
for at løse dette problem skal du se på Codeigniter-dokumentation. Ifølge den tager forespørgslen () – funktionen to parametre. Den første er forespørgslen, og den anden er de parametre, du vil binde.
eksempel 1
denne funktion filtrerer som standard alle de bindede parametre for at forhindre injektioner. Her er et eksempel på den rigtige måde at bruge denne funktion 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 giver en anden måde at udføre en sådan anmodning vil forhindre injektioner. Her er et eksempel på at bruge Active Record-klassen til at forhindre:
$this->db->get_where('users',array('username'=>$this->input->post('username') ,'password' => $this->input->post('password')));
hvordan man forhindrer CakePHP-indsprøjtningsangreb i CakePHP ?
CakePHP er en hurtig udviklingsramme for PHP, der bruger almindeligt kendte designmønstre som associativ datakortlægning, Front Controller og MVC. CakePHP tilbyder en masse indbygget komponent for at lette udviklingen af internetapplikationer og vil gøre dem mere sikre.
CakePHP-apps er dog også sårbare over for injektioner, hvis de ikke bruges godt. Her er et eksempel på en sårbar kode til indsprøjtningsangreb i denne ramme:
$results = $connection-> execute('SELECT * FROM users WHERE username = '. $this->request->getParam('username').' AND password='. $this->request->getParam('password'))->fetchAll('assoc');
funktionen udfør () bruger som standard de forberedte udsagn. Det foregående eksempel er dog stadig sårbart over for indsprøjtningsangreb, da brugerdataene indsættes direkte i en legitim anmodning. Her er et eksempel på den rigtige måde at bruge denne funktion på:
$results = $connection->execute('SELECT * FROM users WHERE username = :username AND password=:password', )->fetchAll('assoc');
CakePHP-rammen tilbyder også et system kaldet forespørgselsbygger, som tvinger brugerdatafiltrering for at forhindre indsprøjtningsangreb. Ifølge CakePHP-dokumentation, under omslagene, bruger Forespørgselsbyggeren de forberedte udsagn.
her er et eksempel på, hvordan du kan bruge et sådant system på den rigtige måde:
use Cake\ORM\Locator\LocatorAwareTrait;
$users = $this->getTableLocator()->get('users');
// Start a new query.
$query = $users->find();
$query->where();
Sådan forhindrer du indsprøjtningsangreb i FuelPHP ?
FuelPHP er en af de seneste PHP-rammer, der blev født baseret på de bedste ideer fra hver ramme på markedet. Det blev udviklet med PHP 5 og er fuldt objektorienteret. I FuelPHP var sikkerhed fronten og centrum for bekymring, hvilket skubbede sine bidragydere til at implementere mange sikkerhedsmekanismer til at filtrere brugerdata. En af grundene til at implementere sådanne mekanismer i FuelPHP.
men selv med en så stærk ramme sætter en simpel misbrug af disse mekanismer hele koden i fare for et indsprøjtningsangreb. Her er et eksempel på en sådan kodefejl:
$query = "SELECT * FROM article WHERE id = ". Input::get('id');
$result = DB::query($query)->execute();
for at løse dette er der også to teknikker som de andre rammer. Den første er faktisk korrekt at bruge forespørgselsfunktionen () ved at 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 anden løsning er at bruge ORM-mekanismen implementeret i FuelPHP-rammen til at kommunikere med databasen. Her er et eksempel på, hvordan man bruger det:
$user = DB::select()->from('article')->where('id', Input::get('id'))->execute();
Hvordan undgår man at blive ramt af en indsprøjtning ?
send ramme (ændret til Laminas projekt) er en af de mest kendte rammer i verden af PHP. Det blev udviklet med performance tuning i tankerne, hvilket forklarer, hvorfor hver nye version er meget hurtigere end den gamle. Han blev også udviklet med den bedste sikkerhedspraksis, som pressede sine udviklere til at implementere yderligere sikkerhedsmekanismer til at håndtere kendte cybertrusler.
nogle af disse mekanismer blev implementeret til at håndtere indsprøjtningsangrebene. Men som altid fører misbrug af disse mekanismer til en sårbar kode. I denne del af artiklen vil jeg vise et eksempel på en sådan fejl:
$adapter->query('SELECT * FROM `article` WHERE `id` = '. $this->getRequest()->getPost('id'));
Sådan løser du denne sårbarhed:
$adapter->query('SELECT * FROM `article` WHERE `id` = ?', );
Leave a Reply