Mis on SQL-i süstimine ja kuidas vältida PHP-rakendusi?

Mis te arvate, kas teie SQL andmebaas on toimiv ja ohutu viivitamatu hävitamise eest? Noh, SQL-i süstimine pole nõus!


Jah, see on viivitamatu hävitamine, millest me räägime, sest ma ei taha seda artiklit avada tavapärase lamava terminoloogiaga „turvalisuse karmistamine“ ja „pahatahtliku juurdepääsu takistamine“. SQL-i süstimine on raamatus nii vana trikk, et kõik, iga arendaja, teavad sellest väga hästi ja teavad hästi, kuidas seda ära hoida. Välja arvatud see üks veider aeg, kui nad libisevad üles, ja tulemused võivad olla midagi katastroofilist.

Kui te juba teate, mis on SQL-i süstimine, minge julgelt edasi artikli teise poole juurde. Neile, kes alles astuvad välja veebiarenduse valdkonnas ja unistavad vanemate rollide võtmisest, on mõni sissejuhatus korras.

Mis on SQL-i süstimine?

SQL-i süstimise mõistmise võti on selle nimes: SQL + Injection. Sõnal „süstimine“ ei ole siin meditsiinilisi tähendusi, see on pigem verbi „süsti“ kasutamine. Need kaks sõna annavad koos idee SQL-i veebirakendusse panemisest.

SQL-i paigutamine veebirakendusse. . . hmmm. . . Kas pole niikuinii see, mida me teeme? Jah, kuid me ei taha, et ründaja meie andmebaasi juhib. Mõistagem seda näite abil.

Oletame, et ehitate kohaliku e-poe jaoks tüüpilist PHP-veebisaiti, nii et otsustate lisada kontaktvormi järgmiselt:

Sinu nimi

Sinu sõnum

Ja oletame, et fail send_message.php salvestab kõik andmebaasi, et poe omanikud saaksid hiljem kasutaja sõnumeid lugeda. Sellel võib olla mingi kood:

<?php

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

// kontrollige, kas sellel kasutajal on juba teade
mysqli_query ($ conn, "VALI * kirjadest, kus nimi = $ nimi");

// Muu kood siin

Nii et esmalt proovite teada saada, kas sellel kasutajal on juba lugemata kiri. Päring SELECT * kirjadest, kus nimi = $ nimi tundub piisavalt lihtne, eks?

VIGA!

Oleme oma süütuses avanud uksed meie andmebaasi viivitamatuks hävitamiseks. Selleks peab ründaja vastama järgmistele tingimustele:

  • Rakendus töötab SQL-andmebaasis (täna on peaaegu kõik rakendused)
  • Praegusel andmebaasiühendusel on andmebaasi muutmis- ja kustutamisõigused
  • Oluliste tabelite nimesid võib ära arvata

Kolmas punkt tähendab, et nüüd, kui ründaja teab, et teil on e-poe pood, salvestate suure tõenäosusega tellimuste andmed tellimuste tabelisse. Selle kõigega relvastatud ründaja peab tegema ainult oma nime:

Joe; kärpida tellimusi;? Jah, härra! Vaatame, mis saab päringust, kui see PHP-skriptiga käivitatakse:

VALI * teadetest, kus nimi = Joe; kärpida tellimusi;

Okei, päringu esimeses osas on süntaksiviga (tsitaate ei ole „Joe” ümber), kuid semikoolon sunnib MySQL-i mootorit uut tõlgendama: kärpima tellimusi. Nii, nagu ühe hoobiga, on kogu tellimuste ajalugu kadunud!

Nüüd, kui teate, kuidas SQL Injection töötab, on aeg vaadata, kuidas see peatada. Kaks SQL-i eduka sisestamise tingimust peavad olema:

  1. PHP-skriptil peaksid andmebaasis olema õigused muutmiseks / kustutamiseks. Arvan, et see kehtib kõigi rakenduste kohta ja te ei saa oma rakendusi muuta ainult lugemiseks. Ja arvake ära, isegi kui eemaldame kõik modifitseerimise õigused, võib SQL-i süstimine siiski lubada kellelgi SELECT-päringuid käivitada ja vaadata kogu andmebaasi, kaasa arvatud tundlikud andmed. Teisisõnu, andmebaasidele juurdepääsu taseme vähendamine ei toimi ja teie rakendus vajab seda igal juhul.
  2. Kasutaja sisendit töödeldakse. Ainus viis, kuidas SQL-i süstimine toimib, on see, kui aktsepteerite kasutajatelt andmeid. Jällegi ei ole otstarbekas peatada kõiki rakenduse sisestusi ainult seetõttu, et olete mures SQL-i süstimise pärast.

SQL-i sisestamise tõkestamine PHP-s

Arvestades, et andmebaasiühendused, päringud ja kasutajate sisendid on osa elust, kuidas vältida SQL-i süstimist? Õnneks on see üsna lihtne ja seda saab teha kahel viisil: 1) puhastada kasutajate sisestatud andmed ja 2) kasutada ettevalmistatud avaldusi.

Puhastage kasutaja sisestatud andmed

Kui kasutate vanemat PHP-versiooni (5.5 või vanemat ja seda juhtub palju ka jagatud hostimise korral), on mõistlik käivitada kogu kasutaja sisend funktsiooni mysql_real_escape_string () kaudu. Põhimõtteliselt eemaldab see stringi kõik erimärgid, nii et need kaotavad andmebaasi kasutamisel oma tähenduse.

Näiteks kui teil on string, näiteks ma olen string, saab ründaja kasutada ühe pakkumise märki (‘) loodava andmebaasi päringu manipuleerimiseks ja SQL-i süstimiseks. Selle käitamine mysql_real_escape_string () kaudu annab tulemuseks stringi, mis lisab ühele tsitaadile kaldkriipsu, väljudes sellest. Selle tulemusel edastatakse kogu string kahjutu stringina andmebaasi, selle asemel et osaleda päringu manipuleerimises.

Sellel lähenemisviisil on üks puudus: see on tõesti väga vana tehnika, mis käib koos PHP andmebaasidele juurdepääsu vanemate vormidega. Alates PHP 7-st pole seda funktsiooni enam isegi olemas, mis viib meid järgmise lahenduseni.

Kasutage ettevalmistatud avaldusi

Valmistatud avaldused on viis andmebaasipäringute turvalisemaks ja usaldusväärsemaks tegemiseks. Idee on see, et töötlemata päringu andmebaasi saatmise asemel räägime kõigepealt andmebaasile selle päringu struktuuri. Seda mõtleme avalduse koostamise all. Kui avaldus on koostatud, edastame selle teabe parameetriliste sisenditena, et andmebaas saaks lünki täita, sisestades sisendid varem saadetud päringustruktuuri. See võtab ära sisendite võimaliku erivõimsuse, mistõttu neid tuleb kogu protsessis käsitleda pelgalt muutujatena (või kui soovite). Valmistatud avaldused näevad välja järgmised:

<?php
$ serverinimi = "kohalik vaim";
$ kasutajanimi = "kasutajanimi";
$ parool = "parool";
$ dbname = "myDB";

// Loo ühendus
$ conn = new mysqli ($ serverinimi, $ kasutajanimi, $ parool, $ dbname);

// Kontrollige ühendust
if ($ konn->connect_error) {
surema ("Ühendus nurjus: " . $ konn->ühenda_error);
}

// valmistada ja köita
$ stmt = $ conn->valmistama ("INSERT INTO MyGuests (eesnimi, perekonnanimi, e-post) VÄÄRTUSED (?,?,?)");
$ stmt->bind_param ("sss", $ eesnimi, $ perekonnanimi, $ e-post);

// määrake parameetrid ja käivitage
$ eesnimi = "John";
$ perekonnanimi = "Doe";
$ email = "[e-posti aadress on kaitstud]";
$ stmt->täitma ();

$ eesnimi = "Maarja";
$ perekonnanimi = "Moe";
$ email = "[e-posti aadress on kaitstud]";
$ stmt->täitma ();

$ eesnimi = "Julie";
$ perekonnanimi = "Dooley";
$ email = "[e-posti aadress on kaitstud]";
$ stmt->täitma ();

kaja "Uute kirjete loomine õnnestus";

$ stmt->Sulge();
$ konn->Sulge();
?>

Ma tean, et protsess kõlab tarbetult keerukana, kui olete ettevalmistatud avaldustega uus, kuid kontseptsioon on vaeva väärt. Siin on kena sissejuhatus sellele.

Neile, kes on juba tuttavad PHP kaitstud päritolunimetuse laiendiga ja kasutavad seda ettevalmistatud avalduste loomiseks, on mul väike nõuanne.

Hoiatus: olge kaitstud päritolunimetuse seadistamisel ettevaatlik

Kui kasutate andmebaasi kasutamiseks kaitstud päritolunimetust, võime sattuda vale turvatunde juurde. „Noh, ma kasutan kaitstud päritolunimetust. Nüüd ei pea ma mõtlema millelegi muule ”- nii läheb meie mõtlemine üldiselt. On tõsi, et kaitstud päritolunimetusest (või MySQLi koostatud avaldustest) piisab igasuguste SQL-i süstimisrünnakute ärahoidmiseks, kuid selle seadistamisel peate olema ettevaatlik. Tavaline on, et lihtsalt kopeeritakse ja kleepitakse kood õpetustest või varasematest projektidest ja minnakse edasi, kuid see säte võib kõik tühistada:

$ dbÜhendamine->setAttribute (KPN :: ATTR_EMULATE_PREPARES, tõsi);

Selle sätte eesmärk on käsitada KPN-il jäljendada ettevalmistatud avaldusi, mitte aga kasutada andmebaasi ettevalmistatud avalduste funktsiooni. Järelikult saadab PHP andmebaasi lihtsad päringustringid, isegi kui teie kood näeb välja justkui ettevalmistatud väljavõtteid ja parameetrite seadistamist. Teisisõnu, olete SQL-i süstimise suhtes sama haavatav kui varem. ��

Lahendus on lihtne: veenduge, et see emuleerimine oleks vale.

$ dbÜhendamine->setAttribute (KPN :: ATTR_EMULATE_PREPARES, vale);

Nüüd on PHP-skript sunnitud kasutama ettevalmistatud avaldusi andmebaasi tasemel, hoides ära igasuguseid SQL-i süstimisi.

WAF-i kasutamise takistamine

Kas teate, et saate veebirakendusi kaitsta ka SQL-i süstimise eest, kasutades WAF-i (veebirakenduse tulemüür)?

Noh, mitte ainult SQL-i süstimine, vaid ka paljud teised 7. kihi haavatavused, näiteks saidiülene skriptimine, katkine autentimine, saidiülene võltsimine, andmete kokkupuude jne. Võite kasutada ka ise hostitavaid nagu Mod Security või pilvepõhiseid järgmisi.

SQL-i süstimine ja kaasaegsed PHP-raamistikud

SQL-süstimine on nii tavaline, nii lihtne, nii pettumust valmistav ja nii ohtlik, et kõik kaasaegsed PHP-veebiraamistikud on sisse ehitatud vastumeetmetega. Näiteks WordPressis on meil $ wpdb->valmista () funktsioon, samas kui kasutad MVC raamistikku, teeb see sinu jaoks kogu räpase töö ja sa ei pea isegi mõtlema SQL-i süstimise ennetamisele. Pisut tüütu on see, et WordPressis peate avaldusi selgesõnaliselt ette valmistama, aga hei, see on WordPress, millest me räägime. ��

Igatahes, minu mõte on see, et kaasaegne veebiarendajate rühm ei pea mõtlema SQL-i süstimisele ja selle tulemusel pole nad isegi selle võimalusest teadlikud. Isegi kui nad jätavad oma rakenduses ühe tagaukse lahti (võib-olla on see $ _GET päringu parameeter ja vanad harjumused räpase päringu käivitamiseks), võivad tulemused olla katastroofilised. Seega on alati parem võtta aega, et sukelduda sügavamale vundamentidesse.

Järeldus

SQL-i süstimine on väga vastik rünnak veebirakenduse vastu, kuid seda on lihtne vältida. Nagu nägime sellest artiklist, on kasutaja sisendi töötlemisel ettevaatlik (muide, SQL-i süstimine pole ainus oht, mida kasutaja sisendi käsitlemine toob) ja andmebaasist päringute tegemiseks on kõik olemas. See tähendab, et me ei tööta alati veebiraamistiku turvalisuses, seega on parem olla seda tüüpi rünnakutest teadlik ja mitte langeda nende alla..

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