Mikä on SQL-injektio ja kuinka estää PHP-sovellukset?

Joten luuletko SQL-tietokantasi toimivana ja turvassa välittömältä tuhoutumiselta? No, SQL-injektio on eri mieltä!


Kyllä, kyse on välittömästä tuhoamisesta, josta puhumme, koska en halua avata tätä artikkelia, jolla on tavanomainen surullinen terminologia “turvallisuuden tiukentaminen” ja “haitallisen pääsyn estäminen”. SQL-injektio on niin vanha temppu kirjassa, että jokainen, jokainen kehittäjä, tietää siitä erittäin hyvin ja tietää hyvin, kuinka sitä voidaan estää. Lukuun ottamatta sitä outoa aikaa, kun ne liukuvat ylös, ja tulokset voivat olla vain tuhoisia.

Jos tiedät jo SQL-injektio, siirry vapaasti artikkelin loppuosaan. Mutta niille, jotka ovat vasta aloittamassa verkkokehityksen alalla ja haaveilevat siirtyäkseen vanhempiin tehtäviin, jotkut johdannosta ovat kunnossa.

Mikä on SQL-injektio?

Avain SQL-injektioiden ymmärtämiseen on sen nimessä: SQL + Injection. Sana ”injektio” ei sisällä mitään lääketieteellisiä merkityksiä, vaan on verbi “injektoi”. Yhdessä nämä kaksi sanaa välittävät ajatuksen SQL: n asettamisesta verkkosovellukseen.

SQL: n asettaminen verkkosovellukseen. . . hmmm. . . Eikö se ole sitä, mitä teemme muuten? Kyllä, mutta emme halua hyökkääjän ajavan tietokantamme. Ymmärretään tämä esimerkin avulla.

Oletetaan, että rakennat tyypillistä PHP-verkkosivustoa paikalliselle verkkokaupalle, joten päätät lisätä seuraavan lomakkeen:

Sinun nimesi

Viestisi

Oletetaan, että tiedosto send_message.php tallentaa kaiken tietokantaan, jotta myymälän omistajat voivat lukea käyttäjän viestejä myöhemmin. Sillä voi olla tällainen koodi:

<?php

$ nimi = $ _POST [‘nimi’];
$ viesti = $ _POST [‘viesti’];

// tarkista, onko tällä käyttäjällä jo viesti
mysqli_query ($ Conn, "VALITSE * viesteistä, joissa nimi = $ nimi");

// Muu koodi täällä

Joten yrität ensin selvittää, onko tällä käyttäjällä jo lukematon viesti. Kysely SELECT * viesteistä, joissa nimi = $ nimi vaikuttaa riittävän yksinkertaiselta, eikö niin?

VÄÄRÄ!

Syyttömyydessämme olemme avanneet ovet tietokantamme välittömään tuhoamiseen. Jotta tämä tapahtuisi, hyökkääjän on täytettävä seuraavat ehdot:

  • Sovellus toimii SQL-tietokannassa (nykyään melkein kaikki sovellukset ovat)
  • Nykyisellä tietokantayhteydellä on “muokata” ja “poistaa” käyttöoikeudet tietokantaan
  • Tärkeiden taulukoiden nimet voidaan arvata

Kolmas kohta tarkoittaa, että nyt kun hyökkääjä tietää, että sinulla on verkkokauppa, tallennat todennäköisesti tilaustiedot tilaustaulukkoon. Kaikkien tämän kanssa aseellisesti hyökkääjän on tehtävä vain toimittaa tämä heidän nimensä:

Joe; katkaista tilaukset? Kyllä herra! Katsotaan mitä kyselystä tulee, kun se suoritetaan PHP-skriptilla:

VALITSE * viesteistä, KOS nimi = Joe; katkaista tilaukset;

Okei, kyselyn ensimmäisessä osassa on syntaksivirhe (ei lainauksia “Joen” ympärillä), mutta puolipiste kaksoispiste pakottaa MySQL-moottorin aloittamaan tulkinnan uuden: katkaista tilaukset. Aivan kuten koko tilaushistoria on kadonnut yhdellä kerralla!

Nyt kun tiedät, miten SQL-injektio toimii, on aika pohtia sitä. Kaksi ehtoa, jotka on täytettävä onnistuneelle SQL-injektiolle, ovat:

  1. PHP-komentosarjalla pitäisi olla muokata / poistaa käyttöoikeuksia tietokannassa. Mielestäni tämä pätee kaikkiin sovelluksiin, etkä voi tehdä sovelluksistasi vain luku -tyyppisiä. �� Ja arvaa mitä, vaikka poistamme kaikki muokkausoikeudet, SQL-injektio voi silti antaa jonkun suorittaa SELECT-kyselyitä ja tarkastella kaikkia tietokantoja, mukaan lukien arkaluontoiset tiedot. Toisin sanoen tietokannan käyttöoikeustason vähentäminen ei toimi, ja sovellus tarvitsee sitä joka tapauksessa.
  2. Käyttäjän syöttämiä tietoja käsitellään. Ainoa tapa, jolla SQL-injektio voi toimia, on, kun hyväksyt tietoja käyttäjiltä. Jälleen kerran, ei ole käytännöllistä pysäyttää kaikkia sovelluksesi syötteitä vain siksi, että olet huolissasi SQL-injektiosta.

SQL-injektioiden estäminen PHP: ssä

Nyt kun otetaan huomioon, että tietokantayhteydet, kyselyt ja käyttäjän syötteet ovat osa elämää, miten estetään SQL-injektio? Onneksi se on melko yksinkertainen, ja on kaksi tapaa tehdä se: 1) puhdistaa käyttäjän syöttämät tiedot ja 2) käyttää valmisteltuja lausuntoja.

Puhdista käyttäjän syöttämät tiedot

Jos käytät vanhempaa PHP-versiota (5.5 tai vanhempi, ja tämä tapahtuu paljon jaetussa isännöinnissä), on viisasta suorittaa kaikki käyttäjän antamat tiedot toiminnolla nimeltään mysql_real_escape_string (). Periaatteessa mitä se tekee, se poistaa kaikki merkkijonon erikoismerkit niin, että ne menettävät merkityksensä tietokannan käyttäessä.

Esimerkiksi, jos sinulla on merkkijono, kuten minä olen merkkijono, hyökkääjä voi käyttää yksittäistä tarjousmerkkiä (‘) manipuloidakseen luotavaa tietokantakyselyä ja aiheuttaa SQL-injektion. Suorittamalla se mysql_real_escape_string (): lla tuotan merkkijonon, joka lisää yksittäislainaukseen selkän viivan ja pakenee sen. Seurauksena on, että koko merkkijono siirretään nyt vaarattomana merkkijonona tietokantaan sen sijaan, että se voisi osallistua kyselyn manipulointiin.

Tällä lähestymistavalla on yksi haittapuoli: se on todella, todella vanha tekniikka, joka kulkee PHP: n vanhempien tietokantakäyttömuotojen kanssa. PHP 7: stä lähtien tätä toimintoa ei ole edes olemassa, mikä vie meidät seuraavaan ratkaisuomme.

Käytä valmisteltuja lausuntoja

Valmistetut lausunnot ovat tapa tehdä tietokantakyselyjä turvallisemmin ja luotettavammin. Ajatuksena on, että raakakyselyn lähettämisen sijaan tietokantaan kerrotaan ensin tietokannalle lähettämämme kyselyn rakenne. Tätä tarkoitamme lausunnon valmistelemisella. Kun lausunto on laadittu, siirrämme tiedot parametrisoiduina panoksina, jotta tietokanta voi ”täyttää aukot” kytkemällä tulot aiemmin lähettämäämme kyselyrakenteeseen. Tämä vie pois kaikki syötteillä mahdollisesti olevat erityiset voimat, jolloin niitä käsitellään pelkkinä muuttujina (tai tarvittaessa hyötykuormina) koko prosessissa. Valmistellut lausunnot näyttävät seuraavalta:

<?php
$ palvelimen nimi = "paikallinen isäntä";
$ käyttäjänimi = "käyttäjätunnus";
$ salasana = "Salasana";
$ dbname = "mydb";

// Luo yhteys
$ conn = uusi mysqli ($ palvelimen nimi, $ käyttäjänimi, $ salasana, $ dbname);

// Tarkista yhteys
if ($ conn->connect_error) {
kuolla("Yhteys epäonnistui: " . $ Conn->connect_error);
}

// valmistele ja sido
$ stmt = $ conn->valmistella("INSERT INTO MyGuests (etunimi, sukunimi, sähköposti) ARVOT (?,?,?)");
$ stmt->bind_param ("SSS", $ etunimi, $ sukunimi, $ sähköposti);

// aseta parametrit ja suorita
$ etunimi = "Johannes";
$ sukunimi = "naarasjänis";
$ email = "[Email protected]";
$ stmt->suorittaa();

$ etunimi = "Maria";
$ sukunimi = "Moe";
$ email = "[Email protected]";
$ stmt->suorittaa();

$ etunimi = "Julie";
$ sukunimi = "Dooley";
$ email = "[Email protected]";
$ stmt->suorittaa();

kaiku "Uusien tietueiden luominen onnistui";

$ stmt->kiinni();
$ Conn->kiinni();
?>

Tiedän, että prosessi kuulostaa tarpeettoman monimutkaiselta, jos olet uusi valmistelemiin lausuntoihin, mutta konsepti on vaivan arvoinen. tässä mukava johdanto siihen.

Niille, jotka tuntevat jo PHP: n SAN-laajennuksen ja käyttävät sitä valmistettujen lauseiden luomiseen, minulla on pieni neuvo.

Varoitus: Ole varovainen määrittäessäsi alkuperänimitystä

Kun käytät suojattujen alkuperänimitysten avulla tietokantaan pääsyä, voimme imeytyä väärään turvatunteeseen. ”No, käytän SAN-merkintää. Nyt minun ei tarvitse miettiä mitään muuta ”- näin ajattelumme yleensä menee. On totta, että SAN (tai MySQLi: n laatimat lausunnot) riittää kaikenlaisten SQL-injektiohyökkäysten estämiseen, mutta sinun on oltava varovainen asettaessasi sitä. On tavallista, että vain kopioidaan ja liitetään koodi opetusohjelmista tai aiemmista projekteista ja siirrytään eteenpäin, mutta tämä asetus voi kumota kaiken:

$ dbConnection->setAttribute (SAN: ATTR_EMULATE_PREPARES, tosi);

Tämä asetus tarkoittaa, että PDO: lle vaaditaan jäljittelemään valmisteltuja lauseita sen sijaan, että käytettäisiin tietokannan valmistettuja lauseita -ominaisuutta. Tämän seurauksena PHP lähettää tietokantaan yksinkertaiset kyselyjonot, vaikka koodisi näyttää luomalla valmisteltuja lauseita ja asetusparametreja. Toisin sanoen, olet yhtä haavoittuvainen SQL-injektiolle kuin ennen. ��

Ratkaisu on yksinkertainen: varmista, että tämä emulointi on asetettu väärään.

$ dbConnection->setAttribute (SAN: ATTR_EMULATE_PREPARES, väärä);

Nyt PHP-skripti pakotetaan käyttämään valmisteltuja lausuntoja tietokantatasolla, estäen kaikenlaiset SQL-injektiot.

WAF: n käytön estäminen

Tiedätkö, että voit myös suojata verkkosovelluksia SQL-injektiolta WAF: n (verkkosovelluksen palomuuri) avulla?

No, ei vain SQL-injektio, mutta monet muutkin kerroksen 7 haavoittuvuudet, kuten sivustojenväliset komentosarjat, rikkoutunut todennus, sivustojenvälinen väärentäminen, tietojen altistuminen jne. Voit käyttää joko itse isännöimää, kuten Mod Security tai pilvipohjaista, seuraavina.

SQL-injektio ja nykyaikaiset PHP-kehykset

SQL-injektio on niin yleistä, niin helppoa, niin turhauttavaa ja niin vaarallista, että kaikki nykyaikaiset PHP-verkkokehykset ovat sisäänrakennettu vastatoimenpiteillä. Esimerkiksi WordPressissä meillä on $ wpdb->valmista () -toiminto, kun taas jos käytät MVC-kehystä, se tekee kaiken likaisen työn puolestasi, eikä sinun tarvitse edes ajatella SQL-injektioiden estämistä. On vähän ärsyttävää, että WordPressissä sinun on laadittava lausunnot nimenomaisesti, mutta hei, se on WordPress, josta puhumme. ��

Joka tapauksessa minun huomautukseni on, että nykyaikaisen web-kehittäjien rotujen ei tarvitse ajatella SQL-injektiota, ja sen seurauksena he eivät edes tiedä mahdollisuudesta. Sinänsä, vaikka he jättäisivät yhden takaoven auki sovelluksessaan (ehkä se on $ _GET-kyselyparametri ja vanhat tavat ampua likainen kysely potkua sisään), tulokset voivat olla katastrofaalisia. Joten on aina parempi käyttää aikaa sukeltaa syvemmälle säätiöihin.

johtopäätös

SQL-injektio on erittäin ilkeä hyökkäys verkkosovellukseen, mutta sitä vältetään helposti. Kuten tässä artikkelissa näimme, ole huolellinen käyttäjän syötteiden käsittelyssä (muuten SQL-injektio ei ole ainoa uhka, jonka käyttäjän syötteiden käsittely aiheuttaa) ja tietokannan kyselyillä on kaikki mitä sillä on. Toisin sanoen, emme aina työskentele web-puitteiden turvallisuudessa, joten on parempi olla tietoinen tämän tyyppisestä hyökkäyksestä ja olla tekemättä siitä..

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