SQL Injection er en sikkerhetsfeil i webapplikasjoner der angripere setter inn skadelig SQL-kode gjennom brukerinndata. Dette kan tillate dem å få tilgang til sensitive dataendringsdatabaseinnhold eller til og med ta kontroll over systemet. Det er viktig å vite om SQL Injection for å holde nettapplikasjoner sikre.
SQL Injection (SQLi) er et sikkerhetssårbarhet som oppstår når en angriper kan manipulere en nettapplikasjons databasespørringer ved å sette inn ondsinnet SQL-kode i brukerinndatafelt. Disse injiserte spørringene kan manipulere den underliggende databasen for å hente modifisere eller slette sensitive data. I noen tilfeller kan angripere til og med eskalere privilegier og få full kontroll over databasen eller serveren.

Eksempel fra den virkelige verden:
I 2019 skjedde Capital One-databruddet på grunn av en feilkonfigurert nettapplikasjon som tillot en angriper å utnytte en SQL-injeksjonssårbarhet. Dette resulterte i lekkasje av personopplysninger til over 100 millioner kunder, inkludert navn adresser og kredittpoeng.
SQL-injeksjonssikkerhetsnivå
DVWA tilbyr fire sikkerhetsnivåer for SQL-injeksjon for å hjelpe elever med å se hvordan ulike beskyttelser påvirker angrep:
1. Lav sikkerhet
Appen tar innspillet ditt og legger det direkte inn i SQL-spørringen uten filtrering.
$id = $_GET['id'];$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';- Går inn
':Bryter spørringen og får databasen til å sende en feil som viser at den er sårbar. - Går inn
1' OR '1'='1:Lurer søket til alltid å være sant, slik at alle brukere returneres. - Går inn
1' UNION SELECT user password FROM users--:Blir med i et annet søk for å hente skjulte data som brukernavn og passord.
2. Middels sikkerhet
Appen bruker grunnleggende inndatasanering ved å bruke funksjoner somaddslashes()å rømme'.
$id = addslashes($_GET['id']);$query = 'SELECT first_name last_name FROM users WHERE user_id = '$id';';Hvordan kan være angrep:
En enkel'injeksjon vil ikke fungere lenger (fordi den blir').
Men angripere kan fortsatt omgå ved å bruke numerisk injeksjon (siden tall ikke trenger anførselstegn).
Eksempel:
gjøre skriptet kjørbart
1 OR 1=1Dette returnerer fortsatt alle poster.
3. Høy sikkerhet
Appen bruker forberedte uttalelser (parameteriserte spørringer) for å håndtere brukerinndata på en sikker måte.
$stmt = $pdo->prepare('SELECT first_name last_name FROM users WHERE user_id = ?');$stmt->execute([$id]);Angrep:
Forsøk som' OR 1=1ellerUNION SELECTfungerer ikke lenger.
Spørringen behandler alle inndata som data, ikke SQL-kode.
Typer SQL-injeksjon
Det finnes forskjellige typer SQL-injeksjon
1. Feilbasert SQL-injeksjon
Feilbasert SQL-injeksjon er en type in-band SQL-injeksjon der en angriper med vilje får databasen til å generere en feilmelding. Angriperen analyserer deretter denne feilmeldingen for å få verdifull informasjon om databasens struktur som tabellnavn og kolonnenavn som kan brukes til å lage ytterligere mer presise angrep.
Hvordan det fungerer
Dette angrepet retter seg mot applikasjoner som avslører rå databasefeil i stedet for å vise generiske meldinger. Ved å injisere ondsinnet input som bryter SQL-syntaksen utløser angripere disse feilene og får verdifulle ledetråder om databasestrukturen.
sammenligne i java
- Identifiser en sårbar inngang: Angriperen finner et inndatafelt som en søkefelt eller en URL-parameter som samhandler direkte med databasen uten riktig inndatarensing.
- Injiser en ondsinnet nyttelast: Angriperen injiserer en spesiell karakter (som et enkelt sitat
') eller en funksjon som er kjent for å forårsake en databasefeil. - Analyser feilen: Databasen som ikke er i stand til å behandle den feilformede spørringen returnerer en detaljert feilmelding. Denne meldingen kan avsløre viktig informasjon som:
- Databasesystemet (f.eks. MySQL Oracle SQL Server).
- Versjonen av databasen.
- Hele SQL-spørringen blir utført.
- Spesifikke syntaksfeil som kan brukes til å forstå tabell- eller kolonnenavn.
- Avgrens angrepet: Ved å bruke informasjonen som er samlet inn fra feilmeldingen, kan angriperen avgrense nyttelasten for å trekke ut mer data som brukernavn og passord.
Eksempel:
Trinn 1: Sett opp miljøet ditt
- Start DVWA. Den er vanligvis tilgjengelig ved å navigere til en URL som
http://localhost/dvwai nettleseren din.
- Logg på DVWA med standard påloggingsinformasjon:
admin/password.
- Gå til kategorien DVWA Security og sett sikkerhetsnivået til lavt. Dette vil sikre at sårbarhetene er enkle å utnytte.
Trinn 2: Identifiser sårbarheten
SQL-injeksjonssiden har en enkel inntastingsboks der du kan angi en bruker-ID. Backend-spørringen er sannsynligvis noe sånt somSELECT * FROM users WHERE id = 'user_input'
- Skriv inn en gyldig ID som
1inn i inndataboksen og klikk "Send". Du bør se detaljene for brukeren med ID 1.
SQL-injeksjonskilde
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 ?> - Prøv nå å bryte søket. Skriv inn et enkelt sitat
'i inndataboksen og send inn.
Spørsmålet blir:
SELECT * FROM users WHERE id = ''';Her ser databasen et ekstra tilbud og vet ikke hvordan den skal fullføre spørringen.
rekke strenger c programmering
I stedet for å vise deg brukerdetaljene vil applikasjonen returnere en SQL-feil (noe sånt som "Du har en feil i SQL-syntaksen ...")
Dette kalles feilbasert SQL-injeksjon fordi:
- Angriperen sender ugyldig input (
') - Databasen gir en feil
- Denne feilen lekker nyttig informasjon om databasen (som type DB antall kolonner struktur osv.)
2. Union-basert SQL-injeksjon
Union-basert SQL Injection er en teknikk der angripere brukerUNIONoperatør for å kombinere resultatene av to eller flereSELECTutsagn i ett enkelt resultatsett. Dette kan tillate dem å trekke ut informasjon fra andre tabeller i databasen. DeUNIONoperatør kan bare brukes hvis:
- Begge søkene har samme antall kolonner
- Kolonnene har lignende datatyper
- Kolonnene er i samme rekkefølge
UNION Operatør : DenUNIONoperator brukes til å kombinere resultatsettet av to eller flereSELECTuttalelser.
- Hver
SELECTuttalelse innenforUNIONmå ha samme antall kolonner - Kolonnene må ha lignende datatyper
- Kolonnene må være i samme rekkefølge
SELECT column_name(s) FROM table1UNIONSELECT column_name(s) FROM table2Eksempel:
Trinn 1: Først må vi finne antall kolonner i den eksisterende tabellen på nettstedet for å injisere UNION-basert SQL-injeksjon:
SQL-injeksjonssiden har en enkel inntastingsboks der du kan angi en bruker-ID. Backend-spørringen er sannsynligvis noe sånt som
SELECT * FROM users WHERE id = 'user_input'Prøv nå å bryte søket. Skriv inn et enkelt sitat'i inndataboksen og send inn.
Hvis applikasjonen er sårbar, får du en detaljert feilmelding. Det kan se noe slikt ut:
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
Trinn 2: BrukUNIONNøkkelord for å finne antall kolonner
For å brukeUNIONsøkeord (et vanlig neste trinn) må du vite antall kolonner i den opprinnelige spørringen. Dette kan du finne ut ved å brukeORDER BYklausul
navn på by i usa
- Prøv å sortere resultatene etter kolonne
1:1 ORDER BY 1.
- Send inn. Det burde fungere.
SQL-injeksjonskilde
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; } } ?> - Øk antallet:
1 ORDER BY 2. Send inn. Det burde fungere.
- Fortsett å øke til du får en feilmelding. For eksempel
1 ORDER BY 4kan gi deg:Unknown column '4' in 'order clause' - Dette betyr at spørringen har 3 kolonner.
3. Blind-basert SQL-injeksjon
Blind SQL-injeksjon oppstår når angripere ikke kan se søkeresultater direkte på nettsiden. I stedet utleder de informasjon fra subtile endringer i applikasjonens oppførsel eller responstid. Selv om den er tregere og mer kjedelig enn klassisk SQLi, kan den være like effektiv.
I stedet for å få tilbake data, utleder angriperen informasjon ved å observere nettsidens oppførsel. Dette gjøres vanligvis på en av to måter:
- Boolsk-basert blind SQLi: Angriperen injiserer en SQL-spørring som returnerer en ekte eller falsk resultat. Nettapplikasjonens svar endres basert på om spørringen er sann eller usann. For eksempel kan siden vise en annen melding eller gjengi en annen layout.
- Tidsbasert blind SQLi: Angriperen injiserer en SQL-spørring som får databasen til å utføre en tidkrevende handling (som en
SLEEP()funksjon) hvis en betingelse er oppfylt. Angriperen observerer tiden det tar før siden lastes inn for å finne ut om den injiserte tilstanden var sann eller usann.
Eksempel:
Se for deg en påloggingsside hvor du skriver inn brukernavn og passord. Applikasjonen konstruerer en SQL-spørring som dette:
SELECT * FROM users WHERE username = 'user_input' AND password = 'password_input'En blind SQL-injeksjon vil innebære å manipulereuser_inputfeltet for å stille databasen et spørsmål.
I stedet for å få et direkte svar kan angriperen prøve noe slikt:
user_input = 'admin' AND 1=1; --Hvis siden laster normalt, vet angriperen det1=1er en ekte uttalelse.
js array
user_input = 'admin' AND 1=2; --Hvis siden viser en feil eller oppfører seg annerledes, vet angriperen det1=2er en falsk uttalelse.
Ved å bruke en serie av disse sanne/falske spørsmålene kan en angriper systematisk gjette og trekke ut informasjon ett tegn om gangen. Prosessen kan automatiseres for å gjette alt fra tabellnavn til brukerpassord.
Virkningen av SQL-injeksjonsangrep
- Uautorisert tilgang til sensitive data : Angripere kan hente personlig økonomisk eller konfidensiell informasjon som er lagret i databasen.
- Problemer med dataintegritet : Angripere kan endre slette eller ødelegge kritiske data som påvirker applikasjonens funksjonalitet.
- Eskalering av privilegier : Angripere kan omgå autentiseringsmekanismer og få administrative rettigheter.
- Nedetid for tjenesten : SQL-injeksjon kan overbelaste serveren og forårsake ytelsesforringelse eller systemkrasj.
- Skade på omdømmet : Et vellykket angrep kan alvorlig skade omdømmet til en organisasjon som fører til tap av kundetillit.
Forebygging av SQL-injeksjonsangrep
Det er flere gode fremgangsmåter for å forhindre SQL-injeksjonsangrep:
1. Bruk Prepared Statements og Parameterized Queries
Forberedte setninger og parametriserte spørringer sikrer at brukerinndata behandles som data i stedet for en del av SQL-spørringen. Denne tilnærmingen eliminerer risikoen for SQL-injeksjon.
Eksempel i PHP (ved hjelp av MySQLi):
$stmt = $conn->prepare('SELECT * FROM users WHERE username = ? AND password = ?'); $stmt->bind_param('ss' $username $password); $stmt->execute();2. Bruk lagrede prosedyrer
Lagrede prosedyrer er forhåndsdefinerte SQL-spørringer lagret i databasen. Disse prosedyrene kan bidra til å forhindre SQL-injeksjon fordi de ikke konstruerer SQL-spørringer dynamisk.
Eksempel:
CREATE PROCEDURE GetUserByUsername (IN username VARCHAR(50)) BEGIN SELECT * FROM users WHERE username = username; END;3. Godkjenning av inndatavalidering
Sørg for at brukerinndata er validert før de brukes i SQL-spørringer. Tillat bare visse tegn og mønstre, for eksempel alfanumerisk inntasting for felt som brukernavn eller e-postadresser.
4. Bruk ORM Frameworks
Object-Relational Mapping (ORM) rammeverk som Gå i dvale eller Entitetsrammeverk kan bidra til å forhindre SQL-injeksjon ved automatisk å håndtere spørringsgenerering og forhindre dynamisk spørringskonstruksjon.
5. Begrens databaserettigheter
Gi brukere de minste nødvendige databasetillatelsene. Sørg for at applikasjoner bare kan utføre nødvendige handlinger (f.eks. VELG INSERT) og begrense tillatelser som DROP TABLE eller ALTER.
6. Feilhåndtering
Konfigurer databasen og applikasjonen til ikke å vise detaljerte feilmeldinger til brukeren. Logg i stedet feil internt og vis generiske feilmeldinger til sluttbrukere.