Guffa | Foto | Programmering

SQL injections på ett nytt sätt

Att skydda sig som SQL injections genom att se till att man inte kan bryta sig ut ur en sträng med hjälp av apostrofer kanske du känner till. Visste du att man kan göra SQL injections med alla värden som skickas till databasen, även de som inte är strängar?

Nej, det visste du nog inte. Jag ser varje dag exempel på kod som är helt öppen för SQL injections, men det var först idag (2004-04-12) som jag tänkte på det.

Titta på den här koden:

strSQL = "select UserName from Users where UserId=" & Request.Querystring("id")

Den ser ju inte så farlig ut, eller hur?

Ifall jag ändrar lite i querystring när jag anropar sidan, så blir det dock ganska illla... Ifall jag skriver så här i querystring:
?id=42;drop%20table%20Users
så kommer databasfrågan som skapas att se ut så här:

select UserName from Users where UserId=42;drop table Users

Häpp! Tabellen är spårlöst borta.



(tid för eftertanke...)



Hur gör man då för att skydda sig mot detta?

Det är ganska enkelt, och jag har själv gjort det i flera år utan att jag har tänkt på det. Jag gjorde det för att få bättre struktur i koden, och idag kom jag på att det också är ett ypperligt skydd mot SQL injections.

Värdet man får ifrån Request.Querystring() är alltid en sträng. För att skydda sig så ser man ser helt enkelt till att konvertera alla värden till tal som ska innehålla tal. Ifall någon försöker smyga in något annat så kommer det ett felmeddelande istället för att dina tabeller försvinner.

Ifall Request.Querystring("id") alltid ska finnas, så är det bara att konvertera det till ett tal och lägga i en variabel:

lngUserId = CLng(Request.Querystring("Id"))

Ifall en querystring bara ska finnas i vissa fall, så får du kolla ifall den finns, och lägga in ett annat värde i variabeln ifall den inte finns:

' kolla ifall en querysrting finns
If Request.Querystring("Id").Count = 0 Then
   lngUserId = - 1 ' värde som betyder att det inte fanns något
Else
   lngUserId = CLng(Request.Querystring("Id"))
End If

Ifall du lägger in alla värden ifrån Request.Querystring och Request.Form i variabler på det här sättet, och ser till att värden som ska vara tal verkligen blir omvandlade till tal, så får du full kontroll på vad som kommer in till sidan, och du har ett fullgott skydd mot SQL injections.

Dessutom får du några positiva bieffekter:

1. Bättre ordning och reda i koden
2. Koden blir snabbare
3. Du får mindre problem med datatyper som inte passar

Göran Andersson