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

Gegengifte für SQL Injection

Geschrieben von: Christoph Wille
Kategorie: Sicherheit

This printed page brought to you by AlphaSierraPapa

Im Artikel SQL Injection habe ich demonstriert, was darunter zu verstehen ist, und wie es funktioniert. Heute wollen wir uns die diversen Gegenstrategien ansehen, um SQL Injection in Zukunft zu verhindern. Darunter fällt wie schon im gestrigen Artikel erwähnt validieren, validieren, validieren und ein Umstellen des Codes auf nicht anfällige Konstrukte.

Es gilt Michael Howard's Regel: All input is evil, until proven otherwise!

Und wie findet man nun heraus, ob der Input good oder evil ist? Man kann es entweder händisch (mit Stringfunktionen) machen, oder sich endlich mit Regular Expressions anfreunden. Gerade Regular Expressions (reguläre Ausdrücke) sind die ultimative Power bei der Überprüfung von Input. Sie sind sehr vielseitig, und erlauben eine Validierung, die man mit normalen Stringfunktionen nicht leicht hinbekommt.

Dieser Artikel kann und will keine Einführung in Regular Expressions sein. Aber ein guter Start- und Referenzpunkt, schließlich geht es ja um Validierung von Input. Ein guter Startpunkt ist der Artikel Reguläre Ausdrücke / Regular Expressions, und wer RegEx'en in Aktion sehen möchte, sollte den Artikel Webseiten automatisiert scrapen, Teil 2 lesen. Und wer ein tolles Archiv an RegEx'en sein eigen nennen will, soll die Website Regular Expression Library besuchen - man kann ohne eigenen Erfindungsreichtum die Regular Expressions anderer weiterverwenden. Es ist also einfach, wenn man nur weiß, wo man die RegEx'en fertig herbekommt.

Validieren, validieren, validieren. Nicht vergessen.

Hat man den Input auf Gültigkeit abgeklopft, sollte man nicht den Fehler machen, trotzdem die selben fehleranfälligen SQL Konstrukte weiterzuverwenden. Man könnte unter Umständen ja ein Attackeszenario vergessen haben. Für die Umstellung bieten sich bei SQL Server zwei Varianten an:

Parametrisierte Kommandos

Parametrisierte Kommandos bieten sich nicht nur für SQL Server an, diese funktionieren auch mit anderen Datenbanken. Generell sieht ein parametrisiertes Kommando für das Loginformular des letzten Artikels so aus:

SELECT COUNT(*) FROM Users WHERE UserName=? AND UserPassword=?

Der große Unterschied ist, daß ich den SQL String nicht mehr dynamisch zusammenbaue. Das Kommando wird über ADO vorbereitet (deshalb findet sich auch oft der Ausdruck prepared statement), man könnte auch sagen vorkompiliert. Im Prinzip ist es eine temporäre Stored Procedure in SQL Server.

Durch diese Parametrisierung ist die Verwendung sehr ähnlich zu einer Stored Procedure:

  strSQL = "SELECT COUNT(*) FROM Users WHERE UserName=? AND UserPassword=?"
  Set cmd = Server.CreateObject("ADODB.Command")
  cmd.CommandText = strSQL
  cmd.CommandType = adCmdText

  ' Kein Parametername wird übergeben
  Set param = cmd.CreateParameter("", adVarChar, adParamInput, nMaxUsernameLength, strUsername)
  cmd.Parameters.Append param
  
  ' Aus Geschwindigkeitsgründen in ASP nicht empfehlenswert
  Set param = Server.CreateObject("ADODB.Parameter")
  param.Type = adVarChar
  param.Direction = adParamInput
  param.Value = strPassword
  param.Size = nMaxPasswordLength
  cmd.Parameters.Append param
  
  cmd.ActiveConnection = strConn 
  Set rs = cmd.Execute()

Auch völlig ohne Validierung funktioniert hier keinerlei SQL Injection mehr (vergesst die Idee gleich wieder, All input is evil, until proven otherwise!).

Der gezeigte Code ist klarerweise ein wenig mehr Aufwand als das einfache zusammenbauen eines SQL Strings, allerdings erspart man sich einiges an Kopfweh (der vollständige Code ist im Download in der Datei FortifiedLogin.asp zu finden). Und übrigens: das funktioniert nicht nur für SELECT, sondern genauso für INSERT, UPDATE oder DELETE.

Hinweis zum Beispielcode: aus Gründen der Klarheit der parametrisierten Kommandos fehlen die Regular Expression Validierungen - und auch deswegen, daß man sehen kann, daß SQL Injection nicht mehr funktioniert. Ebenfalls mit Absicht wird der sa Account verwendet. Läuft das Beispiel unmodifiziert auf Eurem SQL Server, dann habt Ihr ein zu stopfendes Sicherheitsloch!

Stored Procedures

Eine andere und bessere Umstellung des Codes ist die Verwendung von Stored Procedures. Stored Procedures werden am Datenbankserver programmiert, und können dort mit entsprechenden Ausführungsberechtigungen versehen werden (ja, das ist in der Dokumentation zu finden - sogar sehr leicht!). Die Programmierung und Verwendung geht einem mit ein wenig Übung sehr leicht von der Hand, und es ist keineswegs schwarze Magie.

Obwohl ebenfalls keine schwarze Magie, ist das Erstellen des notwendigen ADO Codes zum Aufruf von Stored Procedures lästig. Außer man verwendet den ADO Command Code Generator: einfach den Namen der Stored Procedure eingetippt, und schon wird der ADO Code automatisch generiert. Apropos Stored Procedures: der Artikel Highspeed-Abfragen einer SQL Server Datenbank wäre auch nicht zu verachten, wenn es um Hintergrundwissen zu Stored Procedures, ADO und Performance geht.

Die .NET Programmierer habe ich auch nicht vergessen: für sie hätte ich den Einführungsartikel Stored Procedures 101 in ADO.NET zu empfehlen.

Schlußbemerkung

Damit hätten wir die Punkte Validierung, Validierung, Validierung und Codeumbau abgehandelt. Die Beschreibung ist mit Absicht auf den Punkt gebracht, weil die Beschreibung der jeweiligen Techniken bereits existiert. Ein Kritikpunkt spezifisch für mein Loginformular ist noch, daß die Passwörter in Plaintext in der Datenbank gespeichert werden. Dem kann abgeholfen werden, wie im Artikel Passwörter mit SHA1 absichern nachzulesen ist.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20011031.zip

Verwandte Artikel

Benutzerverwaltung leicht gemacht: Teil 1
http:/www.aspheute.com/artikel/20020429.htm
Der ADO Command Code Generator
http:/www.aspheute.com/artikel/20010308.htm
Ein einfacher Eventkalender für Projektteams
http:/www.aspheute.com/artikel/20020319.htm
Highspeed-Abfragen einer SQL Server Datenbank
http:/www.aspheute.com/artikel/20001013.htm
Passwörter mit SHA1 absichern
http:/www.aspheute.com/artikel/20010330.htm
Records zählen mit Stored Procedures
http:/www.aspheute.com/artikel/20010326.htm
Reguläre Ausdrücke / Regular Expressions
http:/www.aspheute.com/artikel/20000829.htm
SQL Injection
http:/www.aspheute.com/artikel/20011030.htm
Stored Procedures 101 in ADO.NET
http:/www.aspheute.com/artikel/20010626.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
Webseiten automatisiert scrapen, Teil 2
http:/www.aspheute.com/artikel/20010911.htm

Links zu anderen Sites

Regular Expression Library
http://regexlib.com

 

©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.