SQL ievadīšana ir drošības trūkums tīmekļa lietojumprogrammās, kurās uzbrucēji ievieto kaitīgu SQL kodu, izmantojot lietotāja ievadi. Tas var ļaut viņiem piekļūt sensitīviem datiem, mainīt datu bāzes saturu vai pat pārņemt kontroli pār sistēmu. Ir svarīgi zināt par SQL injekciju, lai nodrošinātu tīmekļa lietojumprogrammu drošību.
SQL injekcija (SQLi) ir drošības ievainojamība, kas rodas, ja uzbrucējs var manipulēt ar tīmekļa lietojumprogrammas datu bāzes vaicājumiem, lietotāja ievades laukos ievietojot ļaunprātīgu SQL kodu. Šie ievadītie vaicājumi var manipulēt ar pamatā esošo datubāzi, lai izgūtu modificētu vai dzēstu sensitīvus datus. Dažos gadījumos uzbrucēji var pat palielināt privilēģijas, iegūstot pilnīgu kontroli pār datu bāzi vai serveri.

Reālās pasaules piemērs:
2019. gadā Capital One datu pārkāpums notika nepareizi konfigurētas tīmekļa lietojumprogrammas dēļ, kas ļāva uzbrucējam izmantot SQL injekcijas ievainojamību. Tā rezultātā tika nopludināti vairāk nekā 100 miljonu klientu personas dati, tostarp vārdi, adreses un kredītreitingi.
SQL injekcijas drošības līmenis
DVWA nodrošina četrus SQL injekcijas drošības līmeņus, lai palīdzētu skolēniem redzēt, kā dažādas aizsardzības ietekmē uzbrukumus.
1. Zema drošība
Lietotne ņem jūsu ievadi un tieši ievieto to SQL vaicājumā bez filtrēšanas.
$id = $_GET['id'];$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';- Ienākšana
':Pārtrauc vaicājumu un liek datu bāzei parādīt kļūdu, atklājot, ka tā ir neaizsargāta. - Ienākšana
1' OR '1'='1:Vaicājums vienmēr ir patiess, lai visi lietotāji tiktu atgriezti. - Ienākšana
1' UNION SELECT user password FROM users--:Pievienojas citam vaicājumam, lai iegūtu slēptos datus, piemēram, lietotājvārdus un paroles.
2. Vidēja drošība
Lietojumprogramma izmanto pamata ievades dezinfekciju, izmantojot tādas funkcijas kāaddslashes()lai aizbēgtu'.
$id = addslashes($_GET['id']);$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';Kā var būt uzbrukums:
Vienkāršs'injekcija vairs nedarbosies (jo tā kļūst').
Taču uzbrucēji joprojām var apiet, izmantojot ciparu ievadīšanu (jo cipariem nav vajadzīgas pēdiņas).
Piemērs:
java8 funkcijas
1 OR 1=1Tas joprojām atgriež visus ierakstus.
3. Augsta drošība
Lietotne izmanto sagatavotus paziņojumus (parametrizētus vaicājumus), lai droši apstrādātu lietotāja ievadi.
$stmt = $pdo->prepare('SELECT first_name last_name FROM users WHERE user_id = ?');$stmt->execute([$id]);Uzbrukums:
Mēģinājumi kā' OR 1=1vaiUNION SELECTvairs nestrādā.
Vaicājums visu ievadi apstrādā kā datus, nevis SQL kodu.
SQL injekcijas veidi
Ir dažādi SQL injekcijas veidi
1. Uz kļūdām balstīta SQL injekcijas
Uz kļūdām balstīta SQL injekcija ir joslas SQL injekcijas veids, kurā uzbrucējs apzināti liek datu bāzei ģenerēt kļūdas ziņojumu. Pēc tam uzbrucējs analizē šo kļūdas ziņojumu, lai iegūtu vērtīgu informāciju par datu bāzes struktūru, piemēram, tabulu nosaukumiem un kolonnu nosaukumiem, ko var izmantot turpmāku precīzāku uzbrukumu veidošanai.
Kā tas darbojas
Šis uzbrukums ir vērsts uz lietojumprogrammām, kas atklāj neapstrādātas datu bāzes kļūdas, nevis rāda vispārīgus ziņojumus. Ievadot ļaunprātīgu ievadi, kas pārkāpj SQL sintaksi, uzbrucēji izraisa šīs kļūdas un iegūst vērtīgas norādes par datu bāzes struktūru.
rādīt lietotājiem mysql
- Identificējiet ievainojamu ievadi: Uzbrucējs atrod ievades lauku, piemēram, meklēšanas joslu vai URL parametru, kas tieši mijiedarbojas ar datu bāzi bez atbilstošas ievades sanitizācijas.
- Ļaunprātīgas slodzes ievadīšana: Uzbrucējs ievada īpašu rakstzīmi (piemēram, vienu citātu
') vai funkcija, kas, kā zināms, izraisa datu bāzes kļūdu. - Analizējiet kļūdu: Datubāze nespēj apstrādāt nepareizi veidoto vaicājumu, atgriež detalizētu kļūdas ziņojumu. Šis ziņojums var atklāt svarīgu informāciju, piemēram:
- Datu bāzes sistēma (piemēram, MySQL Oracle SQL Server).
- Datu bāzes versija.
- Tiek izpildīts pilns SQL vaicājums.
- Konkrētas sintakses kļūdas, ko var izmantot, lai saprastu tabulu vai kolonnu nosaukumus.
- Uzlabojiet uzbrukumu: Izmantojot kļūdas ziņojumā iegūto informāciju, uzbrucējs var uzlabot savu lietderīgo slodzi, lai iegūtu vairāk datu, piemēram, lietotājvārdus un paroles.
Piemērs:
1. darbība: iestatiet savu vidi
- Palaidiet DVWA. Parasti tam var piekļūt, pārejot uz URL, piemēram
http://localhost/dvwasavā pārlūkprogrammā.
- Piesakieties DVWA ar noklusējuma akreditācijas datiem:
admin/password.
- Dodieties uz cilni DVWA Security un iestatiet drošības līmeni uz zemu. Tas nodrošinās, ka ievainojamības ir viegli izmantot.
2. darbība. Identificējiet ievainojamību
SQL injekcijas lapā ir vienkāršs ievades lodziņš, kurā varat ievadīt lietotāja ID. Aizmugures vaicājums, iespējams, ir kaut kas līdzīgsSELECT * FROM users WHERE id = 'user_input'
- Ievadiet derīgu ID, piemēram
1ievades lodziņā un noklikšķiniet uz Iesniegt. Jums vajadzētu redzēt detalizētu informāciju par lietotāju ar 1. ID.
SQL injekcijas avots
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 ?> - Tagad mēģiniet pārtraukt vaicājumu. Ievadiet vienu citātu
'ievades lodziņā un iesniedziet.
Vaicājums kļūst:
SELECT * FROM users WHERE id = ''';Šeit datu bāze redz papildu citātu un nezina, kā pabeigt vaicājumu.
gulēt javascript
Tā vietā, lai parādītu lietotāja informāciju, lietojumprogramma atgriezīs SQL kļūdu (piemēram, “Jums ir kļūda jūsu SQL sintaksē…”)
To sauc par kļūdu balstītu SQL injekciju, jo:
- Uzbrucējs nosūta nederīgu ievadi (
') - Datu bāze rada kļūdu
- Šīs kļūdas dēļ tiek nopludināta noderīga informācija par datu bāzi (piemēram, DB kolonnu skaita struktūras veids utt.)
2. Union-Based SQL Injection
Savienībā balstīta SQL injekcija ir paņēmiens, kurā uzbrucēji izmantoUNIONoperatoram, lai apvienotu divu vai vairāku rezultātu rezultātusSELECTpaziņojumus vienā rezultātu kopā. Tas var ļaut viņiem iegūt informāciju no citām datu bāzes tabulām. TheUNIONoperatoru var izmantot tikai tad, ja:
- Abiem vaicājumiem ir vienāds kolonnu skaits
- Kolonnām ir līdzīgi datu tipi
- Kolonnas ir tādā pašā secībā
SAVIENĪBAS operators :UNIONoperators tiek izmantots, lai apvienotu divu vai vairāku rezultātu kopuSELECTpaziņojumiem.
- Katrs
SELECTpaziņojums iekšpusēUNIONjābūt vienādam kolonnu skaitam - Kolonnām ir jābūt līdzīgiem datu tipiem
- Kolonnām jābūt tādā pašā secībā
SELECT column_name(s) FROM table1UNIONSELECT column_name(s) FROM table2Piemērs:
1. darbība: Vispirms mums ir jāatrod vietnē esošās tabulas kolonnu skaits, lai ievadītu UNION balstītu SQL injekciju:
SQL injekcijas lapā ir vienkāršs ievades lodziņš, kurā varat ievadīt lietotāja ID. Aizmugures vaicājums, iespējams, ir kaut kas līdzīgs
SELECT * FROM users WHERE id = 'user_input'Tagad mēģiniet pārtraukt vaicājumu. Ievadiet vienu citātu'ievades lodziņā un iesniedziet.
Ja lietojumprogramma ir neaizsargāta, tiks parādīts detalizēts kļūdas ziņojums. Tas varētu izskatīties šādi:
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. darbība: IzmantojietUNIONAtslēgvārds kolonnu skaita noteikšanai
Lai izmantotuUNIONatslēgvārds (izplatīta nākamā darbība), jums jāzina sākotnējā vaicājuma kolonnu skaits. To var uzzināt, izmantojotORDER BYklauzula
nosauciet pilsētu ASV
- Mēģiniet kārtot rezultātus pēc kolonnas
1:1 ORDER BY 1.
- Iesniegt. Tam vajadzētu strādāt.
SQL injekcijas avots
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; } } ?> - Palieliniet skaitli:
1 ORDER BY 2. Iesniegt. Tam vajadzētu strādāt.
- Turpiniet palielināt, līdz tiek parādīta kļūda. Piemēram
1 ORDER BY 4varētu jums dot:Unknown column '4' in 'order clause' - Tas nozīmē, ka vaicājumam ir 3 kolonnas.
3. Aklo SQL injekcija
Aklā SQL injekcija rodas, ja uzbrucēji nevar redzēt vaicājuma rezultātus tieši tīmekļa lapā. Tā vietā viņi secina informāciju no smalkām izmaiņām lietojumprogrammas darbībā vai reakcijas laikā. Lai gan tas ir lēnāks un nogurdinošāks nekā klasiskais SQLi, tas var būt tikpat efektīvs.
Tā vietā, lai atgūtu datus, uzbrucējs izsecina informāciju, novērojot tīmekļa lapas uzvedību. To parasti veic vienā no diviem veidiem:
- Būla aklās SQLi: Uzbrucējs ievada SQL vaicājumu, kas atgriež a taisnība vai viltus rezultāts. Tīmekļa lietojumprogrammas atbilde mainās atkarībā no tā, vai vaicājums ir patiess vai nepatiess. Piemēram, lapa var parādīt citu ziņojumu vai atveidot citu izkārtojumu.
- Uz laiku balstīta aklā SQLi: Uzbrucējs ievada SQL vaicājumu, kas liek datu bāzei veikt laikietilpīgu darbību (piemēram,
SLEEP()funkcija), ja ir izpildīts kāds nosacījums. Uzbrucējs ievēro laiku, kas nepieciešams lapas ielādei, lai noteiktu, vai ievadītais nosacījums bija patiess vai nepatiess.
Piemērs:
Iedomājieties pieteikšanās lapu, kurā ievadāt lietotājvārdu un paroli. Lietojumprogramma izveido SQL vaicājumu šādi:
SELECT * FROM users WHERE username = 'user_input' AND password = 'password_input'Aklā SQL injekcija būtu saistīta ar manipulācijām aruser_inputlauks, lai uzdotu datubāzei jautājumu.
Tā vietā, lai saņemtu tiešu atbildi, uzbrucējs var mēģināt kaut ko līdzīgu:
user_input = 'admin' AND 1=1; --Ja lapa tiek ielādēta normāli, uzbrucējs to zina1=1ir a taisnība paziņojums.
user_input = 'admin' AND 1=2; --Ja lapā tiek parādīta kļūda vai tā darbojas citādi, uzbrucējs to zina1=2ir a viltus paziņojums.
Izmantojot virkni šo patieso/nepatieso jautājumu, uzbrucējs var sistemātiski uzminēt un iegūt informāciju pa vienai rakstzīmei. Procesu var automatizēt, lai uzminētu visu, sākot no tabulu nosaukumiem un beidzot ar lietotāju parolēm.
SQL injekcijas uzbrukumu ietekme
- Neatļauta piekļuve sensitīviem datiem : uzbrucēji var izgūt personīgo finanšu vai konfidenciālo informāciju, kas glabājas datu bāzē.
- Datu integritātes problēmas : uzbrucēji var mainīt dzēst vai bojāt kritiskos datus, kas ietekmē lietojumprogrammas funkcionalitāti.
- Privilēģiju eskalācija : uzbrucēji var apiet autentifikācijas mehānismus un iegūt administratīvās privilēģijas.
- Pakalpojuma dīkstāve : SQL injekcija var pārslogot serveri, izraisot veiktspējas pasliktināšanos vai sistēmas avārijas.
- Reputācijas kaitējums : veiksmīgs uzbrukums var nopietni kaitēt organizācijas reputācijai, izraisot klientu uzticības zaudēšanu.
SQL injekcijas uzbrukumu novēršana
Ir vairākas labākās prakses, lai novērstu SQL injekcijas uzbrukumus:
1. Izmantojiet sagatavotos paziņojumus un parametrizētos vaicājumus
Sagatavotie priekšraksti un parametrizētie vaicājumi nodrošina, ka lietotāja ievadītie dati tiek uzskatīti par datiem, nevis kā SQL vaicājuma daļa. Šī pieeja novērš SQL injekcijas risku.
Piemērs PHP (izmantojot MySQLi):
$stmt = $conn->prepare('SELECT * FROM users WHERE username = ? AND password = ?'); $stmt->bind_param('ss' $username $password); $stmt->execute();2. Izmantojiet saglabātās procedūras
Saglabātās procedūras ir iepriekš definēti SQL vaicājumi, kas tiek glabāti datu bāzē. Šīs procedūras var palīdzēt novērst SQL injekciju, jo tās dinamiski neveido SQL vaicājumus.
kā java ievadīt virkni uz int
Piemērs:
CREATE PROCEDURE GetUserByUsername (IN username VARCHAR(50)) BEGIN SELECT * FROM users WHERE username = username; END;3. Baltā saraksta ievades apstiprināšana
Pirms lietošanas SQL vaicājumos pārliecinieties, vai lietotāja ievades ir pārbaudītas. Atļaut tikai noteiktas rakstzīmes un modeļus, piemēram, burtciparu ievadi laukos, piemēram, lietotājvārdos vai e-pasta adresēs.
4. Izmantojiet ORM Frameworks
Objektu relāciju kartēšanas (ORM) ietvari, piemēram Pārziemot vai Entītijas ietvars var palīdzēt novērst SQL ievadīšanu, automātiski apstrādājot vaicājumu ģenerēšanu, novēršot dinamisku vaicājumu veidošanu.
5. Ierobežojiet datu bāzes privilēģijas
Piešķiriet lietotājiem minimālās nepieciešamās datu bāzes atļaujas. Pārliecinieties, ka lietojumprogrammas var veikt tikai nepieciešamās darbības (piemēram, SELECT INSERT) un ierobežot atļaujas, piemēram, DROP TABLE vai ALTER.
6. Kļūdu apstrāde
Konfigurējiet datu bāzi un lietojumprogrammu tā, lai lietotājam netiktu rādīti detalizēti kļūdu ziņojumi. Tā vietā reģistrē kļūdas iekšēji un gala lietotājiem parāda vispārīgus kļūdu ziņojumus.