Gegengifte für SQL Injection
Geschrieben von: Christoph Wille 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 KommandosParametrisierte 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 ProceduresEine 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ßbemerkungDamit 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 CodesKlicken Sie hier, um den Download zu starten. Verwandte Artikel
Benutzerverwaltung leicht gemacht: Teil 1 Links zu anderen SitesWenn 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.
©2000-2006 AspHeute.com |