SQL Injection je varnostna napaka v spletnih aplikacijah, kjer napadalci prek uporabniškega vnosa vstavijo škodljivo kodo SQL. To jim lahko omogoči dostop do občutljivih podatkov, spremembo vsebine zbirke podatkov ali celo prevzem nadzora nad sistemom. Pomembno je vedeti o SQL Injection, da bodo spletne aplikacije varne.
SQL Injection (SQLi) je varnostna ranljivost, ki se pojavi, ko lahko napadalec manipulira s poizvedbami baze podatkov spletne aplikacije z vstavljanjem zlonamerne kode SQL v uporabniška vnosna polja. Te vstavljene poizvedbe lahko manipulirajo z osnovno bazo podatkov, da pridobijo, spremenijo ali izbrišejo občutljive podatke. V nekaterih primerih lahko napadalci celo povečajo privilegije in pridobijo popoln nadzor nad bazo podatkov ali strežnikom.

Primer iz resničnega sveta:
Leta 2019 je do kršitve podatkov Capital One prišlo zaradi napačno konfigurirane spletne aplikacije, ki je napadalcu omogočila izkoriščanje ranljivosti vbrizgavanja SQL. To je povzročilo uhajanje osebnih podatkov več kot 100 milijonov strank, vključno z imeni, naslovi in kreditnimi ocenami.
Raven varnosti vbrizgavanja SQL
DVWA ponuja štiri varnostne ravni za SQL Injection, ki učencem pomagajo videti, kako različne zaščite vplivajo na napade:
1. Nizka varnost
Aplikacija sprejme vaš vnos in ga neposredno vnese v poizvedbo SQL brez filtriranja.
$id = $_GET['id'];$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';- Vstopanje
':Prekine poizvedbo in baza podatkov vrže napako, ki razkrije, da je ranljiva. - Vstopanje
1' OR '1'='1:Prevara poizvedbo, da je vedno resnična, tako da so vrnjeni vsi uporabniki. - Vstopanje
1' UNION SELECT user password FROM users--:Pridruži se drugi poizvedbi za pridobivanje skritih podatkov, kot so uporabniška imena in gesla.
2. Srednja varnost
Aplikacija uporablja osnovno razkuževanje vnosa s funkcijami, kot jeaddslashes()pobegniti'.
$id = addslashes($_GET['id']);$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';Kako je lahko napad:
Enostavno'injekcija ne bo več delovala (ker postane').
Toda napadalci lahko še vedno zaobidejo z uporabo numerične injekcije (ker številke ne potrebujejo narekovajev).
primer:
edinstven ključ mysql
1 OR 1=1To še vedno vrne vse zapise.
3. Visoka varnost
Aplikacija uporablja pripravljene izjave (parametrizirane poizvedbe) za varno obdelavo uporabniškega vnosa.
$stmt = $pdo->prepare('SELECT first_name last_name FROM users WHERE user_id = ?');$stmt->execute([$id]);Napad:
Poskusi kot' OR 1=1ozUNION SELECTne deluje več.
Poizvedba vse vnose obravnava kot podatke in ne kot kodo SQL.
Vrste vbrizgavanja SQL
Obstajajo različne vrste vbrizgavanja SQL
1. Vbrizgavanje SQL na podlagi napak
Vbrizgavanje SQL na podlagi napak je vrsta znotrajpasovnega vbrizgavanja SQL, pri katerem napadalec namenoma povzroči, da zbirka podatkov ustvari sporočilo o napaki. Napadalec nato analizira to sporočilo o napaki, da pridobi dragocene informacije o strukturi zbirke podatkov, kot so imena tabel in imena stolpcev, ki jih je mogoče uporabiti za izdelavo nadaljnjih natančnejših napadov.
Kako deluje
Ta napad cilja na aplikacije, ki razkrijejo neobdelane napake baze podatkov, namesto da bi prikazale generična sporočila. Z vnosom zlonamernega vnosa, ki zlomi sintakso SQL, napadalci sprožijo te napake in pridobijo dragocene namige o strukturi baze podatkov.
tudi model
- Prepoznajte ranljiv vnos: Napadalec najde vnosno polje, kot je iskalna vrstica ali parameter URL, ki je neposredno v interakciji z zbirko podatkov brez ustrezne sanacije vnosa.
- Vbrizgajte zlonamerno obremenitev: Napadalec vstavi poseben znak (kot enojni narekovaj
') ali funkcijo, za katero je znano, da povzroča napako baze podatkov. - Analizirajte napako: Baza podatkov, ki ne more obdelati napačno oblikovane poizvedbe, vrne podrobno sporočilo o napaki. To sporočilo lahko razkrije ključne informacije, kot so:
- Sistem baze podatkov (npr. MySQL Oracle SQL Server).
- Različica baze podatkov.
- Celotna poizvedba SQL se izvaja.
- Specifične sintaksne napake, ki jih je mogoče uporabiti za razumevanje imen tabel ali stolpcev.
- Izboljšajte napad: Z uporabo informacij, zbranih iz sporočila o napaki, lahko napadalec izboljša svoj tovor, da pridobi več podatkov, kot so uporabniška imena in gesla.
primer:
1. korak: Nastavite svoje okolje
- Zaženite DVWA. Do njega običajno dostopate tako, da se pomaknete na URL, kot je
http://localhost/dvwav vašem brskalniku.
- Prijavite se v DVWA s privzetimi poverilnicami:
admin/password.
- Pojdite na zavihek Varnost DVWA in nastavite raven varnosti na nizko. To bo zagotovilo enostavno izkoriščanje ranljivosti.
2. korak: Identificirajte ranljivost
Stran SQL Injection ima preprosto vnosno polje, kjer lahko vnesete ID uporabnika. Zaledna poizvedba je verjetno nekaj takegaSELECT * FROM users WHERE id = 'user_input'
- Vnesite veljaven ID, npr
1v polje za vnos in kliknite »Pošlji«. Videti bi morali podrobnosti za uporabnika z ID-jem 1.
Vir vbrizgavanja SQL
PHP $id = $_REQUEST[ 'id' ]; switch ($_DVWA['SQLI_DB']) { case MYSQL: // Check database $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; $result = mysqli_query($GLOBALS['___mysqli_ston'] $query ) or die( ''
. ((is_object($GLOBALS['___mysqli_ston'])) ? mysqli_error($GLOBALS['___mysqli_ston']) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '' ); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo 'ID:
{$id}
First name: {$first}
Surname: {$last}'; } mysqli_close($GLOBALS['___mysqli_ston']); break; case SQLITE: global $sqlite_db_connection; #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']); #$sqlite_db_connection->enableExceptions(true); $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; #print $query; try { $results = $sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo 'ID:
{$id}
First name: {$first}
Surname: {$last}'; } } else { echo 'Error in fetch '.$sqlite_db->lastErrorMsg(); } break; } } ode ?> - Zdaj poskusite prekiniti poizvedbo. Vnesite enojni citat
'v polje za vnos in oddajte.
Poizvedba postane:
SELECT * FROM users WHERE id = ''';Tukaj zbirka podatkov vidi dodatno ponudbo in ne ve, kako dokončati poizvedbo.
java z razdelitvijo nizov
Namesto da bi vam prikazal podrobnosti o uporabniku, bo aplikacija vrnila napako SQL (nekaj takega, kot je 'Imate napako v sintaksi SQL ...')
To se imenuje vbrizgavanje SQL na podlagi napak, ker:
- Napadalec pošlje neveljaven vnos (
') - Baza podatkov vrže napako
- Zaradi te napake uhajajo uporabne informacije o zbirki podatkov (na primer vrsta strukture baze podatkov, število stolpcev itd.)
2. Vbrizgavanje SQL na podlagi unije
Vbrizgavanje SQL na podlagi unije je tehnika, pri kateri napadalci uporabljajoUNIONoperator za združevanje rezultatov dveh ali večSELECTizjave v en sam niz rezultatov. To jim lahko omogoči pridobivanje informacij iz drugih tabel v bazi podatkov. TheUNIONoperater se lahko uporablja le, če:
- Obe poizvedbi imata enako število stolpcev
- Stolpci imajo podobne vrste podatkov
- Stolpci so v istem vrstnem redu
Operater UNION : TheUNIONse uporablja za združevanje nabora rezultatov dveh ali večSELECTizjave.
- Vsak
SELECTizjava znotrajUNIONmora imeti enako število stolpcev - Stolpci morajo imeti podobne vrste podatkov
- Stolpci morajo biti v enakem vrstnem redu
SELECT column_name(s) FROM table1UNIONSELECT column_name(s) FROM table2primer:
1. korak: Najprej moramo poiskati število stolpcev obstoječe tabele na spletnem mestu za vbrizgavanje vbrizgavanja SQL na podlagi UNION:
Stran SQL Injection ima preprosto vnosno polje, kjer lahko vnesete ID uporabnika. Zaledna poizvedba je verjetno nekaj takega
SELECT * FROM users WHERE id = 'user_input'Zdaj poskusite prekiniti poizvedbo. Vnesite enojni citat'v polje za vnos in oddajte.
Če je aplikacija ranljiva, boste prejeli podrobno sporočilo o napaki. Morda je videti nekako takole:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1
2. korak: UporabiteUNIONKljučna beseda za odkrivanje števila stolpcev
Za uporaboUNIONključna beseda (običajni naslednji korak) morate poznati število stolpcev v prvotni poizvedbi. To lahko ugotovite z uporaboORDER BYklavzula
ime mesta v ZDA
- Poskusite razvrstiti rezultate po stolpcu
1:1 ORDER BY 1.
- Predloži. Moralo bi delovati.
Vir vbrizgavanja SQL
PHP if( isset( $_REQUEST[ 'Submit' ] ) ) { // Get input $id = $_REQUEST[ 'id' ]; switch ($_DVWA['SQLI_DB']) { case MYSQL: // Check database $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; $result = mysqli_query($GLOBALS['___mysqli_ston'] $query ) or die( ''
. ((is_object($GLOBALS['___mysqli_ston'])) ? mysqli_error($GLOBALS['___mysqli_ston']) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '' ); // Get results while( $row = mysqli_fetch_assoc( $result ) ) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo 'ID:
{$id}
First name: {$first}
Surname: {$last}'; } mysqli_close($GLOBALS['___mysqli_ston']); break; case SQLITE: global $sqlite_db_connection; #$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']); #$sqlite_db_connection->enableExceptions(true); $query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';'; #print $query; try { $results = $sqlite_db_connection->query($query); } catch (Exception $e) { echo 'Caught exception: ' . $e->getMessage(); exit(); } if ($results) { while ($row = $results->fetchArray()) { // Get values $first = $row['first_name']; $last = $row['last_name']; // Feedback for end user echo 'ID:
{$id}
First name: {$first}
Surname: {$last}'; } } else { echo 'Error in fetch '.$sqlite_db->lastErrorMsg(); } break; } } ?> - Povečaj število:
1 ORDER BY 2. Predloži. Moralo bi delovati.
- Povečujte, dokler se ne prikaže napaka. Na primer
1 ORDER BY 4vam lahko da:Unknown column '4' in 'order clause' - To pomeni, da ima poizvedba 3 stolpce.
3. Slepo vbrizgavanje SQL
Slepo vbrizgavanje SQL se zgodi, ko napadalci ne morejo videti rezultatov poizvedbe neposredno na spletni strani. Namesto tega sklepajo na informacije iz subtilnih sprememb v obnašanju ali odzivnem času aplikacije. Čeprav je počasnejši in bolj dolgočasen kot klasični SQLi, je lahko enako učinkovit.
Namesto da bi napadalec podatke pridobil nazaj, jih pridobi z opazovanjem vedenja spletne strani. To se običajno izvede na enega od dveh načinov:
- Slepi SQLi na podlagi logičnih vrednosti: Napadalec vstavi poizvedbo SQL, ki vrne a res oz lažno rezultat. Odziv spletne aplikacije se spremeni glede na to, ali je poizvedba resnična ali napačna. Stran lahko na primer prikaže drugačno sporočilo ali upodobi drugačno postavitev.
- Časovno zasnovani slepi SQLi: Napadalec vstavi poizvedbo SQL, ki povzroči, da zbirka podatkov izvede zamudno dejanje (kot je
SLEEP()funkcija), če je pogoj izpolnjen. Napadalec opazuje čas, potreben za nalaganje strani, da ugotovi, ali je bil vstavljeni pogoj resničen ali neresničen.
primer:
Predstavljajte si prijavno stran, kjer vnesete uporabniško ime in geslo. Aplikacija sestavi poizvedbo SQL takole:
SELECT * FROM users WHERE username = 'user_input' AND password = 'password_input'Slepa injekcija SQL bi vključevala manipulacijo zuser_inputpolje, da bazi podatkov postavite vprašanje.
Namesto neposrednega odgovora lahko napadalec poskusi nekaj takega:
user_input = 'admin' AND 1=1; --Če se stran naloži normalno, napadalec to ve1=1je a res izjava.
user_input = 'admin' AND 1=2; --Če stran prikaže napako ali se obnaša drugače, napadalec to ve1=2je a lažno izjava.
Z uporabo niza teh resničnih/napačnih vprašanj lahko napadalec sistematično ugiba in izvleče informacije en znak naenkrat. Postopek je mogoče avtomatizirati, da ugane vse, od imen tabel do uporabniških gesel.
Vpliv napadov z vbrizgavanjem SQL
- Nepooblaščen dostop do občutljivih podatkov : Napadalci lahko pridobijo osebne finančne ali zaupne podatke, shranjene v bazi podatkov.
- Težave s celovitostjo podatkov : Napadalci lahko spremenijo, izbrišejo ali poškodujejo kritične podatke, ki vplivajo na funkcionalnost aplikacije.
- Stopnjevanje privilegijev : Napadalci lahko obidejo mehanizme za preverjanje pristnosti in pridobijo skrbniške privilegije.
- Izpad storitve : Vbrizgavanje SQL lahko preobremeni strežnik, kar povzroči poslabšanje zmogljivosti ali zrušitve sistema.
- Poškodba ugleda : Uspešen napad lahko resno škoduje ugledu organizacije in povzroči izgubo zaupanja strank.
Preprečevanje napadov z vbrizgavanjem SQL
Obstaja več najboljših praks za preprečevanje napadov z vbrizgavanjem SQL:
1. Uporabite pripravljene izjave in parametrizirane poizvedbe
Pripravljeni stavki in parametrizirane poizvedbe zagotavljajo, da se uporabniški vnosi obravnavajo kot podatki in ne kot del poizvedbe SQL. Ta pristop odpravlja tveganje vbrizgavanja SQL.
Primer v PHP (z uporabo MySQLi):
$stmt = $conn->prepare('SELECT * FROM users WHERE username = ? AND password = ?'); $stmt->bind_param('ss' $username $password); $stmt->execute();2. Uporabite shranjene postopke
Shranjene procedure so vnaprej določene poizvedbe SQL, shranjene v bazi podatkov. Ti postopki lahko pomagajo preprečiti vbrizgavanje SQL, ker ne sestavljajo dinamično poizvedb SQL.
vlc prenos videoposnetkov iz youtuba
primer:
CREATE PROCEDURE GetUserByUsername (IN username VARCHAR(50)) BEGIN SELECT * FROM users WHERE username = username; END;3. Preverjanje vnosa na beli seznam
Zagotovite, da so uporabniški vnosi potrjeni, preden se uporabijo v poizvedbah SQL. Dovolite samo določene znake in vzorce, kot je alfanumerični vnos za polja, kot so uporabniška imena ali e-poštni naslovi.
4. Uporabite ogrodja ORM
Okviri objektno-relacijskega preslikave (ORM), kot je Hibernacija oz Ogrodje entitete lahko pomaga preprečiti vbrizgavanje SQL s samodejnim obravnavanjem generiranja poizvedbe, ki preprečuje dinamično konstrukcijo poizvedbe.
5. Omejite privilegije baze podatkov
Uporabnikom dodelite minimalna zahtevana dovoljenja za bazo podatkov. Prepričajte se, da lahko aplikacije izvajajo samo nujna dejanja (npr. SELECT INSERT) in omejite dovoljenja, kot sta DROP TABLE ali ALTER.
6. Obravnava napak
Konfigurirajte bazo podatkov in aplikacijo, da uporabniku ne prikažeta podrobnih sporočil o napakah. Namesto tega zapisujte napake interno in končnim uporabnikom prikažite splošna sporočila o napakah.