Just nu i M3-nätverket
Gå till innehåll

Sql-Injection i Querystring


Dahlgren

Rekommendera Poster

Hej!

 

Har ytterligare en fråga om SQL Injection. Det är nämligen så att jag läste i en guide hur man kunde skydda sig mot detta att det är möjligt att tillämpa SQL Injection genom querystring.

 

Men jag undrar om detta gäller access-databaser...

 

Det stod att en besökare kunde skriva såhär:

 

users.asp?id=125;drop table users

 

Nu testade jag detta på ett utav mina system men det fungerade inte. Det enda som stod var något i stil med "Tecken i slutet av SQL-uttryck".

 

Och då har jag inte konverterat querystring-datan till ett tal.

 

Någon som vet om jag behöver konvertera querystring-variabelvärdena när jag använder access?

 

Mvh

 

Länk till kommentar
Dela på andra webbplatser

Olle Nyrén

Om du kör Access och ASP och din fråga ser ut så här:

sql = "SELECT * FROM users WHERE id=" & Request.Querystring("id")

kan du eventuellt anropa den med

users.asp?id=125;drop%20table%20users;

Hur man måste skriva beror på hur frågan ser ut. Man bör alltid kontrollera att användaren skickat det man förväntar sig.

 

mvh

Olle

 

Länk till kommentar
Dela på andra webbplatser

Min SQL ser ut såhär:

 

strSQL = "SELECT * FROM user WHERE user.user_id=" & user_id

 

Och user_id i SQL:en ovan är:

user_id = Request.Querystring("user_id")

 

Sedan kör jag oConn.Execute(strSQL), då får jag felet:

 

Microsoft OLE DB Provider for ODBC Drivers (0x80040E14)

[Microsoft][Drivrutin för ODBC Microsoft Access] Tecken efter slutet av SQL-uttryck.

 

Så jag kan inte se någon anledning egentligen att man skulle behöva köra en Clng() eller liknande....

 

Mvh

 

Länk till kommentar
Dela på andra webbplatser

Anjuna Moon

Det finns flera injections man kan göra. Ett enkelt sätt att testa om någon missat detta vid ex. inloggning är att ange användarnamn och lösenord som: (häng med med alla fnuttar nu)

' OR 'a'='a

vilket skulle generera en query liknande:

SELECT UserId FROM UserData WHERE UserName='' OR 'a'='a'

om du skrivit den som:

SELECT UserId FROM UserData WHERE UserName='" & strUser & "'"

 

Beroende på hur du sedan använder resultatet så kommer man med största sannolikhet att kunna logga in, eftersom queryn returnerar hela tabellens innehåll.

 

[inlägget ändrat 2004-04-30 10:07:34 av Anjuna Moon]

Länk till kommentar
Dela på andra webbplatser

Anjuna Moon

För att återgå till din fråga. Om du skickar den qs du beskrev, dvs: id=125;drop table users så kommer din variabel user_id att innehålla STRÄNGEN "25;drop table users" eftersom querystrings separeras av & och inte ; som sql gör. Alltså kommer din query se ut så här:

 

SELECT * FROM user WHERE user.user_id=25;drop table users

 

och såvitt jag vet så fixar inte Access flera satser i en query, separerade med semikolon. (Kan ha fel, det var åratal sen jag rörde skräpet Access)

 

[inlägget ändrat 2004-04-30 10:17:04 av Anjuna Moon]

Länk till kommentar
Dela på andra webbplatser

Nils Adamsson

Fattar inte allt detta snacka om SQL-Injection.

SQL-injection är ett sympton på en väldigt dåligt designad application/dåligt skriven kod.

Säkerhetsrisken som som följer med SQL-Injection är bara ett problem. Det andra är skalbarhet.

Genom att skicka hårdkodade strängar till DB-motorn så

försvarar man avsevärt optimeringen av SQL-satserna.

Ett exempel.

 

select * from adverts where adv_id = 1;

select * from adverts where adv_id = 2;

 

Är 2 totalt olika SQL satser för databse. Båda måste optimeras och detta tar anataglien mer resurser än själva exekveringen. Tänk nu att man har ett system där precis samma fråga återkommer mo och om igen, men där man byter ut värdet på adv_id.

 

Den ända lösningen är bind variabels

 

select * from adverts where adv_id = :P_adv_id;

Sen sätter man bara p_adv_id =2 tex.

Helt plötsligt vet DB motorn att detta är samma fråga som jag redan sett förrut/redan optimerat förrut, så nu är det bara att exekvera. Helt plötsligt har skalbarheten i systemten gått upp 10-faldigt´. Den andra fördelen är ju att hela systemt blivit immunt mot all form av SQL-injection.

 

Så sluta upp med dessa dumheter att bygga SQL med strängar utan bind variables. Det är dålig dålig dålig kod.

 

Tack för orrdet.

 

 

 

 

 

 

Länk till kommentar
Dela på andra webbplatser

Anjuna Moon

Nils Adamsson:

Fattar inte allt detta snacka om SQL-Injection.

 

Ville bara förklara delfrågan om injections. Visst kunde jag också förklarat hur man undviker det, men frågan som ställdes rörde inte det. Kan nog också vara bra för dem som inte känner till detta problem (läs nybörjare, och alla är inte erfarna användare härinne) att få veta HUR man kan sabba en databas på detta sätt.

 

Bara för att du tycker att alla bör ha samma kunskapsnivå som du har, innebär det inte att alla har det. Så sluta upp med DINA dumheter att påpeka detta tack!

 

AnjunaMoon

____________________________________________________________

/* There is nothing more permanent than a temporary solution... */

 

[inlägget ändrat 2004-04-30 10:50:34 av Anjuna Moon]

Länk till kommentar
Dela på andra webbplatser

I asp brukar jag ta för vana att använda egna funktioner i stil med:

Function reqStr(str)
reqStr = Trim(Replace(Request(str), "''", "'"))
End Function

Function reqInt(str)
reqInt = CInt(Request(str))
End Function

 

Länk till kommentar
Dela på andra webbplatser

Ska inte din replace-funktion vara tvärt om?

 

Du skrev:

reqStr = Trim(Replace(Request(str), "''", "'"))

 

Jag tänkte att den kanske skulle se ut såhär:

reqStr = Trim(Replace(Request(str), "'", "''"))

 

Vilket blir rätt?

 

Mvh

 

Länk till kommentar
Dela på andra webbplatser

Nu frågade originalpostaren om Access... Visst går det att använda ett slags stored procedures där också men det är inte så vanligt (AFAIK). Vet inte om det finns någon execution plan eller dyl heller...

 

Länk till kommentar
Dela på andra webbplatser

Nils Adamsson

Oj en liten missuppfatning här tror jag.

SQL separeras inte av ;.

Däremot så separeras satser i tex SQL*Plus av ;

Men SQL*Plus är ett interface till SQL och inte alls samma sak.

 

Här är man på SQL nivå så ; är irrelevant i detta context.

Detta gäller alla DB:s

 

 

 

Länk till kommentar
Dela på andra webbplatser

Nils Adamsson

Paramitiserad frågor tror jag det heter i Access.

Men precis samma princip bara ett annat namn.

 

Länk till kommentar
Dela på andra webbplatser

Anjuna Moon
Detta gäller alla DB:s

 

I SQL Server kan du separera satser med ; när du skickar dem utifrån.

 

Länk till kommentar
Dela på andra webbplatser

Anjuna Moon
Paramitiserad frågor tror jag det heter i Access.

 

"Parametriserade" skulle jag nog tippa att de heter. Vet dock inte hur väl utbyggt detta är.

Förresten finns triggers inbyggda ännu i Access?

 

Länk till kommentar
Dela på andra webbplatser

Nils Adamsson

Jasa så hur tar man hand om resultseten?

Säg att du skickar 5 select statements.

Hur väljer du vilket du loopar genom?

 

 

Som sagt var detta är gränsnittet inte sql själv.

Sen är det en anna sak att man kan göra det

mha av transact-sql. Återigen ej SQL.

 

 

 

 

Länk till kommentar
Dela på andra webbplatser

Anjuna Moon

Jag säger inte att man ska använda det bara att det går. Självklart är det bättre att använda stored proc. Exempel på då jag använde detta innan jag började praktisera SP var exempelvis att köra en Insert och sedan en Select på det id som den nya posten fått. Då passar det bra att köra detta i samma batch. Nog om detta nu.

 

Länk till kommentar
Dela på andra webbplatser

Nils Adamsson

Nja Stored Queries är det engelska namnet för frågor.

Och ett mer generellt begrepp.

Så skall man vara noga så är det väl:

Parameterised Stored Query.

 

Alla stored queries är ju inte Parameterised Stored Queries. I just detta fall så är, när det gäller att undvika

SQL-injection, så är det viktiga att den just är Parameterised. Att inte använda sådana i någon databas är i princip en dödsynd.

 

Länk till kommentar
Dela på andra webbplatser

Om jag inte minns helt fel så är det inte helt entydigt i standarden huruvida ; hör till satsen eller inte. Jag har för mig att SQLServer faktiskt tycker att det är en del av satsen (om man skickar med det).

 

Hur som helst beror det nog väldigt mycket på vad man använder för API för sina databasaccesser om de tar det. PHP tillåter det har jag för mig, kör man JSP så finns det andra mekanismer för att skicka batchar (och få tillbaka multipla resultat). I normalfallet är det klienten som gör det (så är det t.ex i MySQL, Oracle och Informix, ingen av dem tycker att ; är en del av frågan) men utan att för stunden ha möjlighet att testa så skulle jag inte bli ett dugg förvånad om Sybase och SQLServer faktiskt tar det rakt av (och förmodligen skickar tillbaka det sista eller första resultatet.

 

I vilket fall är det knappast något att rekomendera.

 

 

Länk till kommentar
Dela på andra webbplatser

Nils Adamsson

Varför är detta så svårt.

 

Det är skillnad på SQL och programmet som snackar med databasen. Ni blandar ihop päron och äpplen här.

 

; + retur är i princip var en signal till klienten att detta

är slutet på SQL-commandot. Så var vänlig skickas SQL-satsen till databasen. När detta skickas så skickas ej ; med. Databases accepterar inte SQL med ; i slutet.

 

Sen kan klienten vara PHP/JDBC/ODBC/SQL*PLUS

eller vad tusan som helst. Man kan väldigt enkelt skapa

en ny klient som batchar upp SQL commandon avgränsade med <NISSE> om man nu skulle vilja det.

Bara man ser till att klienten inte skickar detta till databasen. Mao detta har inget med datanas att göra bara med vilken klient som snackar med den.

 

 

 

Länk till kommentar
Dela på andra webbplatser

Varför är detta så svårt.

 

Det är skillnad på SQL och programmet som snackar med databasen. Ni blandar ihop päron och äpplen här.

Nej, det enda som händer är att du vägrar acceptera att olika leverantörer har olika definition på vad som är ett äpple och vad som är ett äppleträd. Endel räknar pinnen på äpplet som äpple och andra räknar den till trädet.

 

; + retur är i princip var en signal till klienten att detta

är slutet på SQL-commandot. Så var vänlig skickas SQL-satsen till databasen. När detta skickas så skickas ej ; med. Databases accepterar inte SQL med ; i slutet.

Du har rätt i att det finns databaser som inte accepterar ; som en del av satsen men det finns två tolkningar av vad som gäller, Sybase/SQLServer har en tolkning (där ; är giltigt), de flesta andra har tolkat det som att klienten ska skala bort det hela. Det är faktiskt inte konstigare.

 

Sen kan klienten vara PHP/JDBC/ODBC/SQL*PLUS

eller vad tusan som helst.

Visst kan den det, det är ingen mer än du som håller på och blandar ihop saker. Men var går gränsen tycker du? OleDB är native-interface mot SQLServer, varför skulle det vara en klient? Var börjar isåfall databasen?

Rimligtvis måste det relevanta vara vad databasens egna SQL-tolk klarar av att behandla och i vissa fall så klarar denna verkligen av att man staplar flera SQL-satser på varandra separerade med semikolon, helt enkelt för att det är praktiskt och inte på något sätt bryter mot någon standard (inte för att det brukar stoppa leverantörer).

 

Det finns helt enkelt inte ett rätt och ett fel, i Oracle, MySQL, Informix, PostgreSQL och många många fler så är det "rätt" att ; inte hör till satsen (och faktiskt ger ett syntaxfel om man försöker skicka med det till databasen) men i många andra databaser så är det tvärt om så att det är fullt tillåtet att låta ; lämna klienten och åka rakt in i databasen, om man gör det trots att det bara är en sats så gör det varken till eller från men det kan också gå bra att använda det till att stapla satser.

Det är INTE ett frånsteg från SQL-standarden, det är bara en annan tolkning av den.

 

Jag har under ett drygt decennium sett bägge varianterna och använt hur många API:er (och klienter) som helst mot minst ett tjugotal SQL-databaser och världen är inte så binär i det här fallet som du tror.

 

När det gäller just Injections så är det dessutom helt ointressant om det är databasen eller det API/klient som man använder för att prata med den som klarar av att stapla satser separerade med semikolon, går det så går det och då kan man använda det i injektionsvänlig kod.

Edit: liten omformulering.

[inlägget ändrat 2004-04-30 16:56:38 av fhe]

Länk till kommentar
Dela på andra webbplatser

Magnus Ahlkvist

Du har fel.

 

Semikolon separerar SQL-statements i en batch.

Flera resultatset kan dessutom utan några som helst problem hanteras av ADO (NextRecordset).

--

Snäll ibland. Rättvis nästan jämt. Elak för det mesta.

 

Länk till kommentar
Dela på andra webbplatser

Du har fel.

Han har faktiskt bara delvis fel, ADO hanterar det och om databasen inte har stöd för det så fixar ADO det ändå (har jag för mig), ur ett strikt SQL-perspektiv så är det en Sybase/MSSQL-tolkning av specen och inte en sanning.

Rätt ska vara rätt :-)

 

 

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...