SQL injection beveiliging in classic ASP en Microsoft SQL Server databases. Een SQL injection is aanvalsmethode om een SQL-database te kraken. SQL injectie is verantwoordelijk voor het overgrote deel van gehackte websites, waarbij aanvallers over waardevolle data van bedrijven en instellingen weten buit te maken. Denk hierbij aan financiële, maar ook privacygevoelige gegevens van gebruikers, instellingen, overheden, enz. Kort om, een groot gevaar schuilt in SQL injection, en beveiliging hiertegen is belangrijk!
Naast het gevaar voor het lekken van belangrijke gegevens is SQL injection erg vervelend, bijvoorbeeld als het wordt misbruikt voor het uitvoeren van sleep-aanvallen op MySQL-databaseservers.
Daarom wil je graag een veilige web-applicatie, en daarom SQL injection voorkomen. In dit artikel gaan we in op het voorkomen en tegengaan van SQL injection in, in dit geval, ASP-webapplicaties. We gaan hier in op het gebruik van prepared statements om SQL queries en statements te beveiligen, zodat alleen dat uitgevoerd wordt wat wij willen.
Let op: deze post is opnieuw gepubliceerd, maar inmiddels wel verouderd. Doe zelf goed onderzoek naar technieken om SQL-injection in jouw website-code tegen te gaan! Je vindt hier een voorbeeld ASP naar MySQL en ASP naar SQL Server connectionstring.
Prepared statements in ASP/VBscript om SQL injection tegen te gaan
In ASP is een SQL prepared statement is een goed middel om SQL injection tegen te gaan. De structuur van de query wordt vastgelegd tijdens het prepareren (voorbereiden) van het statement en kan daarna niet meer veranderen. De data waarmee het statement later wordt aangeroepen kan dus de structuur van de query niet meer veranderen, het wordt simpelweg als data behandeld en niet als SQL.
Hierbij maakt het niet uit of je gebruikmaakt van ASP, PHP, Perl of ASP.NET als scripttaal, of Microsoft SQL Server, MySQL of PostgreSQL als databaseserver. Invoervalidatie, prepared statements en beveiliging zijn altijd belangrijk!
Prepared statement met classic ASP/VBScript en MSSQL
Een voorbeeld stukje ASP-/VBScript code met een prepared statement is:
<%
<!--#include file="adovbs.inc"-->
Option Explicit
Dim SqlConn, SqlCommand, resultaat
Set SqlConn = Server.CreateObject("ADODB.Connection")
' gebruik {SQL Server} als Driver als onderstaande niet werkt
SqlConn.Open "Driver={ODBC Driver 17 for SQL Server};" & "Server=host;" &
"DATABASE=databasenaam;" & "uid=gebruikersnaam;" &
"pwd=wachtwoord;"
Set SqlCommand = Server.CreateObject("ADODB.Command")
Set SqlCommand.ActiveConnection = SqlConn
SqlCommand.CommandType = adCmdText
SqlCommand.CommandText = "SELECT * FROM logintable WHERE userid = ? AND wachtwoord= ?"
SqlCommand.Prepared = True
SqlCommand.Parameters.Append (SqlCommand.CreateParameter("@userid", adVarWChar, adParamInput, Len(Request.Form("user_id")), Request.Form("user_id")))
SqlCommand.Parameters.Append (SqlCommand.CreateParameter("@wachtwoord", adVarWChar, adParamInput, Len(Request.Form("passwd")), Request.Form("passwd")))
Set resultaat = SqlCommand.Execute
SqlCommand.Parameters.Delete("@userid")
SqlCommand.Parameters.Delete("@wachtwoord")
%>
Gebruik, zoals hierboven, Option Explicit om vooraf verplicht variabelen te declareren! Dit vermindert de kans op fouten en slordigheidjes. Je vindt een PHP equivalent in het artikel over variabelen declareren.
Hier wordt ADODB.Command object gebruikt om een SQL query te prepareren. Voor MySQL is dit niet veel anders.
HTMLEncode
Naast prepared statements is het verstandig om gebruik te maken van de methode Server.HTMLEncode ([2]), om de code verder te beveiligen. Hiermee worden tekens omgezet naar de HTML-geëncodeerde equivalent, wat goed is tegen cross site scripting. Bijvoorbeeld:
<%
Response.Write(Server.HTMLEncode("The image tag: <img>"))
%>
Prepared Statement query-voorbeelden
Hieronder een aantal prepared statement voorbeelden. Ze zijn verkregen uit het artikel Using Parameterized Queries op Experts Exchange, gepubliceerd door Wayne Barron.
Parameters met tekst VarChar, met een veldlengte van 25
<%
Set chEmail = Server.CreateObject("ADODB.Command")
chEmail.ActiveConnection=objConn
chEmail.Prepared = true
chEmail.commandtext="SELECT cusEmail, password, mydate FROM ordercavecustomer WHERE cusEmail =?"
chEmail.Parameters.Append chEmail.CreateParameter("@cusEmail", adVarChar, adParamInput, 25, loginEmail)
set rschEmail = chEmail.execute
%>
Parameters met een integer (INT – vereist geen lengte)
<%
Set chEmail = Server.CreateObject("ADODB.Command")
chEmail.ActiveConnection=objConn
chEmail.Prepared = true
chEmail.commandtext="SELECT cusEmail, password, myID FROM ordercavecustomer WHERE myID =?"
chEmail.Parameters.Append chEmail.CreateParameter("@myID", adInteger, adParamInput, , getmyID)
set rschEmail = chEmail.execute
%>
Meer dan één parameters, verkregen uit een querystring
Let erop dat je de parameters in de juiste volgorde opgeeft, anders geeft het een fout.
<%
getID = request.QueryString("ID")
getEmail = request.QueryString("Email")
Set chEmail = Server.CreateObject("ADODB.Command")
chEmail.ActiveConnection=objConn
chEmail.Prepared = true
chEmail.commandtext="SELECT cusEmail, password, myID FROM ordercavecustomer WHERE myID =? and cusEmail=?"
chEmail.Parameters.Append chEmail.CreateParameter("@myID", adInteger, adParamInput, , getmyID)
chEmail.Parameters.Append chEmail.CreateParameter("@cusEmail", adVarChar, adParamInput, 25, loginEmail)
set rschEmail = chEmail.execute
%>
Prepared Statement met INSERT
Zorg er weer voor dat alle parameters in de juiste volgorde vermeld staan.
<%
Set chEmail = Server.CreateObject("ADODB.Command")
chEmail.ActiveConnection=objConn
chEmail.commandtext="INSERT into ordercavecustomer(cusEmail, password, myID)values(?,?,?)"
chEmail.Parameters.Append chEmail.CreateParameter("@cusEmail", adVarChar, adParamInput, 25, loginEmail)
chEmail.Parameters.Append chEmail.CreateParameter("@password", adVarChar, adParamInput, 25, loginPass)
chEmail.Parameters.Append chEmail.CreateParameter("@myID", adInteger, adParamInput, , getmyID)
set rschEmail = chEmail.execute
%>
Prepared Statement met UPDATE
Hetzelfde als hiervoor, in de juiste volgorde. De WHERE moet als laatste in de query, en in de parameterlijst.
<%
Set chEmail = Server.CreateObject("ADODB.Command")
chEmail.ActiveConnection=objConn
chEmail.commandtext="update ordercavecustomer set cusEmail=?, password=? where myID=?"
chEmail.Parameters.Append chEmail.CreateParameter("@cusEmail", adVarChar, adParamInput, 25, loginEmail)
chEmail.Parameters.Append chEmail.CreateParameter("@password", adVarChar, adParamInput, 25, loginPass)
chEmail.Parameters.Append chEmail.CreateParameter("@myID", adInteger, adParamInput, , getmyID)
set rschEmail = chEmail.execute
%>
DELETE Statement
Dit voorbeeld verwijdert (DELETE) het item met het opgegeven ID, bijvoorbeeld verkregen uit een querystring
<%
Set chEmail = Server.CreateObject("ADODB.Command")
chEmail.ActiveConnection=objConn
chEmail.commandtext="delete from ordercavecustomer where myID=?"
chEmail.Parameters.Append chEmail.CreateParameter("@myID", adInteger, adParamInput, , getmyID)
set rschEmail = chEmail.execute
%>
Prepared Statements in PHP?
Het artikel Website beveiligen tegen SQL-injection-aanvallen legt je uit hoe je Prepared Statements in PHP gebruikt met MySQLi. Want in PHP is deze beveiliging dit net zo belangrijk!
Conclusie SQL injection voorkomen met ASP en ADODB.Command
Zoals je kunt lezen is beveiliging tegen SQL injection heel erg belangrijk. Niet alleen kunnen kwaadwillende derden vaak eenvoudig inbreken op jouw website en SQL-database, met alle privacygevolgen voor gebruikers van dien. Een SQL injection door middel van sleep()-aanvallen kan zélfs een Denial-of-Service (DoS) veroorzaken en alles onderuit trekken! Daarvan wil jij toch niet de veroorzaker zijn?
De Article werd vermeld op itfaq.nl