Preventing SQL injections in PHP (and other vulnerabilities)

jos olet ollut web development jonkin aikaa, olet lähes varmasti kuullut termin ”SQL injection” ja joitakin kauhistuttavia tarinoita siitä.

PHP, kuten monet muutkin kielet, ei ole immuuni tämäntyyppiselle uhkalle, joka voi olla hyvinkin vaarallinen. Mutta, onneksi, suojella sivustoja SQL injektio ja muita vastaavia uhkia on jotain voit ottaa konkreettisia askeleita kohti.

tässä viestissä opit, mitä SQL-injektio on, mitä onnistuneen hyökkäyksen seuraukset ovat, miten hyökkääjä voi hyödyntää haavoittuvaa PHP-koodia, mitä voit tehdä sen estämiseksi, ja mitä työkaluja voit käyttää havaitsemaan koodin osia, jotka saattavat olla tällaisen uhan kohteena. Lisäksi, opit muutamia muita yleisiä haavoittuvuuksia sinun pitäisi olla tietoinen, jotta luoda turvallisempia sovelluksia.

miten SQL-injektio toimii?

ensimmäinen asia, joka sinun täytyy tietää, jotta voit suojata koodisi SQL-pistokselta, on ymmärtää, miten hyökkääjä voisi käyttää sitä hyväkseen.

idea haavoittuvuuden takana on melko yksinkertainen: hyökkääjä ajaa haitallista SQL-koodia tietokantaasi sovelluksen kautta.

miten kukaan voisi saavuttaa sen? Käyttämällä väärin hakemuksesi syötteitä.

katsotaanpa yksinkertaista esimerkkiä. Oletetaan, että sinulla on sovellus, joka näyttää listan käyttäjänimistä, jossa jokaisella käyttäjällä on linkki tietoihinsa näin:

ja sitten user_details.php – tiedostossa on tämä:

<?php $sql = "SELECT * FROM user WHERE id = ".$_GET;

jos käyttäjä toimii odotetusti ja napsauttaa jonkun käyttäjän nimeä, pyynnön URL-osoite näyttää tältä: http://domain.com/user_details.php?id=8.

Joten, mitä vikaa siinä on?

$sql arvo on merkkijono "SELECT * FROM user WHERE id = 8" ja kysely kulkee ihan hyvin.

ongelma on tämän lauseen kursivoidussa osassa: Jos käyttäjä toimii odotetusti ja napsauttaa jonkun käyttäjän nimeä, pyynnön URL näyttää tältä:

http://domain.com/user_details.php?id=8.

mitä jos käyttäjä ei toimi odotetulla tavalla?

mitä jos joku valmistaisi URL-osoitteen, joka lähettäisi tunnukseksi jotain muuta kuin numeron?

valmistetut URL-osoitteet

jos URL olisi jotain http://domain.com/user_details.php?id=Peanuts, syntyvä SQL-merkkijono olisi: "SELECT * FROM user WHERE id = Peanuts".

tällöin ongelma olisi käyttäjällä. Kysely yksinkertaisesti epäonnistuisi, ja pahimmassa tapauksessa käyttäjä näkisi jonkinlaisen oudon viestin.

but what if the URL look more like this:

http://domain.com/user_details.php?id=1+OR+1%3B? (Tämä on muuten tulos urlencode('1 OR 1;').)

tässä tapauksessa tuloksena oleva SQL olisi "SELECT * FROM user WHERE id = 1 OR 1;". Tämä tarkoittaa, että kyselyn tulos olisi jokainen käyttäjä tietokannassa eikä vain käyttäjä, jonka tunnus on 1. Auts.

mutta sekään ei ole hassumpaa.

kokeillaan nyt rajumpaa esimerkkiä.

oletetaan, että URL oli jotain

http://domain.com/user_details.php?id=1%27%3B+DROP+TABLE+users%3B--+, joka tarkoittaa id=1; DROP TABLE users;--, tuottaa tehokkaasti tämän SQL-komennon:

"SELECT * FROM users WHERE id = 1; DROP TABLE users;-- ". Ja jos teet tämän kyselyn…iso Auts.

jos et ole 100% perehtynyt SQL-syntaksiin, DROP TABLE poistaisi taulukon kokonaan. Kuin sitä ei olisi ollutkaan.

Toki tuore varmistus auttaisi vähentämään vahinkoja, mutta silti. Tämä on paha juttu.

jos haluat oppia lisää tällaisesta hyökkäyksestä, täällä on loistava viesti.

mutta eiköhän siinä ole tarpeeksi huonoja uutisia. Siirrytään iloisempaan paikkaan: miten voit estää tämän tyyppisiä SQL-injektioita PHP-sovelluksissasi.

Miten estää SQL-pistokset PHP: ssä

kuten näit, ongelma on silloin, kun hyökkääjällä on kyky ajaa SQL-koodia ilman, että sinä olet siitä tietoinen.

tämä tilanne ilmenee seurauksena siitä, että lennossa luodaan kyselyitä merkkijonojen yhdistämisen kautta ja että niihin sisältyy ulkoisista syötöistä kerättyjä tietoja (yleensä käyttäjän syöte, mutta myös muista ulkoisista lähteistä, kuten tiedostoista, API-puheluihin annetuista vastauksista ja niin edelleen).

joten, tämän haavoittuvuuden estämiseksi koodissasi, sinun täytyy korjata mahdollisten ongelmien lähteet.

validoi tulosi

yksinkertainen tapa korjata haavoittuvuus yllä olevassa esimerkissä olisi tarkistaa, onko ID-parametri se, mitä siltä todella odotetaan (ts., positiivinen kokonaisluku):

toinen tapa tehdä tällainen validointi on hyödyntää PHP: n sisäänrakennettuja suodattimia:

<?php
$id = filter_input( INPUT_GET, 'id', FILTER_VALIDATE_INT);

joten vahvistamalla syötteesi estät hyökkääjiä suorittamasta haitallista koodia omasi rinnalla.

ei ole helppoa keinoa estää heitä yrittämästä, mutta niin kauan kuin heidän yrityksensä eivät onnistu, olet valmis menemään.

käytä valmiita lausekkeita

toinen tapa suojata koodisi SQL-pistoksilta on käyttää valmiita lausekkeita. Valmiit lauseet ovat valmiiksi käännettyjä SQL-komentoja.

niitä voidaan käyttää tietyn tietokantakirjaston (kuten mysqli) tai yleisemmän San-kirjaston kanssa.

Katsotaanpa esimerkkiä käyttäen mysqli:

jos kokeilet tätä koodia (korvaa tietysti tietokannan tunnistetiedot), näet, että jos käytät laillista URL-osoitetta, kuten http://domain.com/user_details.php?id=1, saat saman tuloksen kuin mikä tahansa yllä olevista haitallisista URL-osoitteista (eli tiedot käyttäjästä, jotka liittyvät ID 1: een eikä mihinkään muuhun).

jos käytät mieluummin San: ää, koodi näyttää enemmänkin tältä:

ei oikeastaan paljon eroa, vai mitä?

tiivistettynä valmiit lausunnot tarjoavat oivan keinon estää SQL-pistokset. Myös, ne yleensä suorittaa paremmin kuin lennossa SQL.

nyt kun tunnet työkalun, sinun tarvitsee vain käyttää sitä.

miten tunnistaa SQL-pistoksille haavoittuva PHP-koodi

kun haavoittuvuus löytyy, sen korjaaminen ei ole varsinaisesti monimutkaista. Mutta miten löydät tällaisia haavoittuvuuksia koodistasi ylipäätään?

No, jos olet onnekas ja koodebaasi on tarpeeksi pieni, yksinkertainen koodin tarkastelu riittää.

mutta jos hakemuksesi on keskikokoinen tai suuri, tarvitset lisäapua.

yksi erittäin suosittu (ja avoimen lähdekoodin) työkalu, jota voit käyttää tähän tarkoitukseen, on sqlmap, yksinkertainen Python-skripti, joka yrittää hyökätä minkä tahansa sille syötetyn URL-osoitteen kimppuun ja raportoida sen löydöistä.

Here ’ s a sample output from a run against a PHP-based website of mine:

toinen avoimen lähdekoodin työkalu on arachni, kehittyneempi työkalu, joka sisältää web GUI ja oli kirjoitettu Ruby.

tässä on näytteen ulostulo sen ajamisesta CLI: n läpi:

koodin tarkastelun ja testauksen lisäksi sinun tulisi harkita RASP-ratkaisun, kuten Sqreenin, käyttöä tuotantoympäristöjen seurantaan, jotta voit lopettaa kaikkien hyötyjen suorittamisen, jotka selviävät tarkastelun ja testauksen vaiheista.

mistä muista haavoittuvuuksista sinun tulisi olla tietoinen?

Code injection

SQL injection on vain yksi suuremman haavoittuvuuksien perheen jäsen: code injection.

eri koodinsyöttötekniikoiden idea on aina sama. Kyse on viattoman sovelluksen huijaamisesta haitallisen koodin käyttöön.

tämä voidaan tehdä monella tavalla.

PHP: ssä on funktioita, jotka on suunniteltu yksinkertaisesti antamaan komentoja suoraan käyttöjärjestelmään, kuten exec – funktio.

tässä yksinkertainen esimerkki siitä, miten tätä voitaisiin hyödyntää:

<?php
exec( 'cp uploads/'.$_GET.' /secure/');

jos joku pyytäisi http://domain.com/exec.php?file=a.txt%3B+rm+-Rf+%2A+%23, tuloksena olisi tämän komennon toteuttaminen:

cp uploads/a.txt; rm -Rf * # /secure/

ja tämä voi pyyhkiä pois koko levyn palvelimella-unvalidated input strikes again!

Cross-site scripting

toinen hyvin yleinen haavoittuvuus on cross-site scripting (XSS). Tässä tapauksessa uhri on sivustossasi vieraileva käyttäjä.

XSS on, kun hyökkääjä ruiskuttaa haitallisen JavaScript-koodin tavallisen HTML-muodon sisään, joka myöhemmin renderoidaan toisen käyttäjän selaimella.

katso tätä PHP-komentosarjaa:

<?php
echo "<html><p>Hello {$_GET}!</p></html>";

on selvää, tarkoituksena on luoda yksinkertainen sivu, joka tervehtii käyttäjää.

mutta kun pahikset pääsevät siihen, mikä estää heitä pyytämästä

http://domain.com/greet.php?name=Mauro%3Cscript+language%3D%22javascript%22%3Ealert%28%22You+are+hacked%21%22%29%3B%3C%2Fscript%3E? Tämä pyyntö tuottaa seuraavan HTML: n tulosteena:

<html><p>Hello Mauro<script language="javascript">alert("You are hacked!");</script></p></html>

tämä on selvästi hyvin naiivi hyödyntää-onhan, mitä haittaa näyttää joku yksinkertainen ” olet hakkeroitu!”viesti? Mutta asiat voivat mennä aika vakaviksi, jos on vähän mielikuvitusta. Muista vain, että jokainen palvelimelle tehty pyyntö sisältää istuntoevästeen, joten tämä haavoittuvuus voi olla syyllinen käyttäjien istuntojen kaappaamiseen.

sitten taas, vaikka ongelmat näyttävät rumilta, korjaukset ovat todella yksinkertaisia: kyse on validoinnista ja puhdistamisesta.

XSS: n tapauksessa riittää yksinkertainen kehotus htmlentities ennen varsinaisen tuotoksen tuottamista.

Fixing vs. detecting security vulnerabilities

kuten näit tässä viestissä, fixing security vulnerabilities—both SQL injections and other types—is not the main challenge. Ymmärtämättä, että koodi on haavoittuva, ja missä sitä voidaan hyödyntää, on. Sinulla on pari vaihtoehtoa täällä:

  • on erittäin vahva koodauskuri
  • testaa sovelluksesi perusteellisesti tietoturvaongelmien varalta
  • käytä seuranta-ja suojaustyökaluja, joilla voit estää hyväksikäytöt ja saada hälytykset ajoissa

minkä valitset, riippuu sinusta. Tärkeää on kiinnittää huomiota näihin ongelmiin ja toimia sen tiedon mukaan. Pysy turvassa.

Leave a Reply

Sähköpostiosoitettasi ei julkaista.