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

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Gegengifte für SQL Injection

Geschrieben von: Christoph Wille
Kategorie: Sicherheit

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
  • Stored Procedures

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.

Download des Codes

Klicken Sie hier, um den Download zu starten.

Verwandte Artikel

Benutzerverwaltung leicht gemacht: Teil 1
Der ADO Command Code Generator
Ein einfacher Eventkalender für Projektteams
Highspeed-Abfragen einer SQL Server Datenbank
Passwörter mit SHA1 absichern
Records zählen mit Stored Procedures
Reguläre Ausdrücke / Regular Expressions
SQL Injection
Stored Procedures 101 in ADO.NET
Verhinderung von SQL Injection Marke .NET
Vorsicht Falle: Dateien, die keine sind
Webseiten automatisiert scrapen, Teil 2

Links zu anderen Sites

Regular Expression Library

Wenn Sie jetzt Fragen haben...

Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten.

Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.

 

Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

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