SQL-injeksjon

SQL-injeksjon er en metode for infiltrasjon av påtrengende kode som bruker en datamaskinsårbarhet som finnes i en applikasjon på inngangsvalideringsnivå for å utføre operasjoner på en database . [ 1 ]

Opprinnelsen til sårbarheten ligger i feil kontroll eller filtrering av variablene som brukes i et program som inneholder eller genererer SQL -kode . Det er faktisk en feil fra en mer generell klasse av sårbarheter som kan oppstå i et hvilket som helst programmeringsspråk eller skript som er innebygd i et annet.

Det er kjent som SQL Injection, utydelig, for typen sårbarhet, metoden for infiltrasjon, faktumet med å bygge inn påtrengende SQL-kode og delen av den innebygde koden.

Beskrivelse

SQL-injeksjon sies å eksistere eller ha skjedd når useriøs SQL-kode på en eller annen måte settes inn eller "injiseres" i programmert SQL-kode for å forstyrre normal drift av programmet og dermed føre til at delen av koden kjøres. "invader" embedded , i databasen .

Denne typen inntrenging er vanligvis av ondsinnet, skadelig eller spionerende natur, derfor er det et datasikkerhetsproblem , og må tas i betraktning av applikasjonsprogrammereren for å forhindre det. Et program utviklet uforsiktig, uforsiktig eller med uvitenhet om problemet, kan vise seg å være sårbart, og sikkerheten til systemet (databasen) kan til slutt bli kompromittert.

Inntrengingen skjer under kjøringen av det sårbare programmet, enten på stasjonære datamaskiner eller på nettsteder , i sistnevnte tilfelle kjører åpenbart på serveren som er vert for dem.

Sårbarheten kan oppstå automatisk når et program "uforsiktig bygger" en SQL-setning ved kjøretid , eller under utviklingsfasen, når programmereren gjør SQL-setningen som skal kjøres ubeskyttet eksplisitt. I alle fall, når programmereren trenger og bruker parametere som skal legges inn av brukeren, for å konsultere en database; siden, nettopp, innenfor parametrene er der den påtrengende SQL-koden kan inkorporeres.

Når spørringen utføres mot databasen , vil den injiserte SQL -koden også bli utført og kan gjøre en rekke ting, for eksempel å sette inn poster, endre eller slette data, autorisere tilgang og til og med utføre andre typer ondsinnet kode på datamaskinen.

For eksempel, forutsatt at følgende kode ligger i en nettapplikasjon og at det er en "brukernavn"-parameter som inneholder brukernavnet som skal søkes, kan en SQL-injeksjon utløses som følger:

Den originale og sårbare SQL-koden er:

consulta := "SELECT * FROM usuarios WHERE nombre = '" + nombreUsuario + "';"

Hvis operatøren skriver et navn, for eksempel "Pepe", vil ingenting unormalt skje, applikasjonen vil generere en SQL-setning som ligner på følgende, som er helt korrekt, der alle postene med navnet "Pepe" i databasen vil være valgte data:

SELECT * FROM usuarios WHERE nombre = 'Pepe';

Men hvis en ondsinnet operatør skriver som brukernavn for å spørre:

Alicia'; DROP TABLE usuarios; SELECT * FROM datos WHERE nombre LIKE '%

, vil følgende SQL-spørring bli generert (den grønne fargen er det programmereren har til hensikt, den blå er dataene og den røde, den injiserte SQL-koden):

SELECT * FROM brukere WHERE name = ' Alice '; DROP TABLE brukere; VELG * FRA data WHERE navn LIKE '% ';

I databasen ville spørringen bli utført i gitt rekkefølge, alle postene med navnet 'Alice' ville bli valgt, 'brukere'-tabellen ville bli slettet og til slutt ville hele 'data'-tabellen bli valgt, som ikke burde være tilgjengelig for vanlige nettbrukere.

Kort sagt, alle data i databasen kan gjøres tilgjengelige for å bli lest eller modifisert av en ondsinnet bruker.

Legg merke til hvorfor det kalles SQL " Injection ". Hvis du ser på den ondsinnede koden, som er rød, vil du legge merke til at den er satt inn i midten av den gode koden, som er grønn. Dermed har den røde koden blitt " injisert " i den grønne.

SQL-injeksjon er lett å unngå, fra programmererens side, i de fleste programmeringsspråkene som tillater utvikling av webapplikasjoner . Dette emnet diskuteres kort i neste avsnitt.

Blind SQL-injeksjon

Blind SQL- injeksjon er en funksjon og angrepsteknikk som bruker SQL- injeksjon . Det er bevist når en nettside, på grunn av en sikkerhetsfeil, ikke viser feilmeldinger da det ikke er noen korrekte resultater når du spør etter databasen, alltid viser det samme innholdet (det vil si at det bare er et svar hvis resultatet er korrekt) . Høyre).

Betingede utsagn med typen "Eller 1=1" eller "ha 1=1" gir alltid riktige svar (sant), og det er derfor de ofte brukes av programmerere som verifikasjonsformer. Problemet for sikkerheten til siden er at denne teknikken brukes i kombinasjon med ordbøker eller brute force for søk, tegn for tegn, av et passord, et brukernavn, et telefonnummer eller annen informasjon som webhotellet angriper. ; For å gjøre dette brukes spesifikk SQL -kode som "tester" hvert tegn, og oppnår et kumulativt positivt resultat når det er samsvar. På denne måten kan du for eksempel vite at et passord starter med "F...", deretter fortsetter med ".i...", og deretter "..r...", etc (akkumulerer Fir.. . ), til du finner hele ordet.

Det finnes programmer som automatiserer denne prosessen med å "sondere" bokstav for bokstav i resultatet av SQL-spørringen, som en angriper kan sende injisert.

Noen måter å unngå SQL Injection

Ruby on Rails

I Ruby on Rails - rammeverket (RoR) verifiseres søk automatisk ved hjelp av en av de inkluderte søkemetodene. For eksempel:

Prosjekt . find query : = "VELG * FRA brukere WHERE name = '" + brukernavn + "';" # eller Prosjekt . finn ( :all , :conditions => { :name => params [ :name ] })

Den eneste måten for en ondsinnet bruker å bruke SQL-injeksjon i RoR er å kode variabelen til streng og bruke den som søkeargument direkte. For eksempel:

# DETTE BØR IKKE GJØRES Prosjekt . finn ( :all , :conditions => "name = ' #{ params [ :name ] } '" )

Perl

I Perl DBI-språket filtrerer DBI::quote - metoden ut spesialtegn (forutsatt at $sql -variabelen inneholder en referanse til et DBI-objekt):

$query = $sql -> prepare ( "SELECT * FROM users WHERE name = " . $sql -> quote ( $username ) );

Eller du kan også bruke plassholderfunksjonen (med automatisk sitering) som følger:

$query = $sql -> prepare ( "SELECT * FROM user WHERE name = ?" ); $query -> kjør ( $brukernavn );

PHP

I PHP -språket er det forskjellige funksjoner som kan hjelpe deg å bruke det med forskjellige databasebehandlingssystemer .

Hvis MySQL brukes , er funksjonen som skal brukes mysql_real_escape_string :

$query_result = mysql_query ( "SELECT * FROM users WHERE name = \" " . mysql_real_escape_string ( $username ) . " \" " );

Det er imidlertid mer anbefalt å bruke alternativer som tilbyr forberedte spørringer som PUD -klassen .

$statement = $pdo -> prepare ( "SELECT * FROM users WHERE name = :name" ); $statement -> bindParam ( ':navn' , $brukernavn ); $statement -> utfør (); $result = $statement -> hent ();

Og hvis MySQLi brukes...

// Med funksjoner $connection = mysqli_connect ( "vert" , "bruker" , "passord" , "dbd" ); $query = mysqli_query ( $connection , "SELECT * FROM users WHERE name = '" . mysqli_real_escape_string ( $connection , $name ) . "'" ); // Objektorientert som arver klassen: $query = $this -> query ( "SELECT * FROM users WHERE name = '" . $this -> real_escape_string ( $name ) . "'" ); // Uten å arve klassen $query = $this -> mysqli -> query ( "SELECT * FROM users WHERE name = '" . $this -> mysqli -> real_escape_string ( $name ) . "'" ); /* hvor $this->mysqli er mysqli-lenken til databasen */

Java

I Java -språket kan PreparedStatement -klassen brukes

I stedet for:

Connection con = ( acquire Connection ) Statement stmt = con . createStatement (); ResultSet rset = stmt . executeQuery ( "SELECT * FROM users WHERE name = '" + brukernavn + "';" );

parameterisering eller variabel escape kan brukes, som angitt i de følgende avsnittene.

Parametrisering av SQL-setninger Connection con = ( kjøp tilkobling ) PreparedStatement pstmt = con . prepareStatement ( "SELECT * FROM users WHERE name = ?" ); pstmt . setString ( 1 , brukernavn ); ResultSet rset = pstmt . executeQuery (); Escape-variabler som skal settes inn i SQL-setningen

Å unnslippe teksten i variabelen ved å erstatte spesialtegnene i SQL med deres tekstlige ekvivalent, slik at SQL tolker hele innholdet i variabelen som om det var tekst.

Connection con = ( acquire Connection ) Statement stmt = con . createStatement (); ResultSet rset = stmt . executeQuery ( "SELECT * FROM users WHERE name = '" + brukernavn . replace ( "\\" , "\\\\" ). replace ( "'" , "\\'" ) + "';" );

Du kan også bruke escapeSQL- metoden til klassen fra Apache Commons Lang -biblioteket.

Connection con = ( acquire Connection ) Statement stmt = con . createStatement (); ResultSet rset = stmt . executeQuery ( "SELECT * FROM users WHERE Name = '" + StringEscapeUtils . escapeSQL ( UserName ) + "';" );

I C#

I C# -språket, fra .NET - plattformen (eller dets gratis alternativ Mono ), er det ADO.NET SqlCommand (for Microsoft SQL Server ) eller OracleCommand (for Oracle-databaseservere). Følgende eksempel viser hvordan du forhindrer kodeinjeksjonsangrep ved å bruke SqlCommand-objektet. Koden for ADO.NET er programmert på lignende måte, selv om den kan variere litt avhengig av hver leverandørs spesifikke implementering.

I stedet for:

ved å bruke ( SqlConnection con = ( skaffe forbindelse ) ) { con . Åpne (); ved å bruke ( SqlCommand cmd = new SqlCommand ( "SELECT * FROM users WHERE name = '" + brukernavn + "'" , med ) ) { using ( SqlDataReader rdr = cmd . ExecuteReader ( ) ){ ... } } }

følgende kan brukes:

ved å bruke ( SqlConnection con = ( skaffe forbindelse ) ) { con . Åpne (); ved å bruke ( SqlCommand cmd = new SqlCommand ( "SELECT * FROM users WHERE name = @username" , with ) ) { cmd . parametere . AddWithValue ( "@brukernavn" , brukernavn ); ved å bruke ( SqlDataReader rdr = cmd . ExecuteReader ( ) ){ ... } } }

Se også

Referanser

  1. "SQL-injeksjon | OWASP» . owasp.org (på engelsk) . Hentet 13. september 2021 . 

Eksterne lenker