Verhinderung von SQL Injection Marke .NET
Geschrieben von: Christoph Wille Was SQL Injection ist, hat der erste Artikel dieser Serie ausführlich erklärt und auch demonstriert. In Folge 2, Gegengifte für SQL Injection, ging es dann um Wege mittels Inputvalidierung SQL Injection zu verhindern, und auch mittels ADO eine Art letzte Bastion zu errichten. Heute wechseln wir von ASP nach ASP.NET, und von ADO zu ADO.NET - und sehen uns die dortigen Abwehrmethoden an. Ich möchte auch heute wieder den Spruch Michael Howard's wiederholen: All input is evil, until proven otherwise! Wie man Input validieren kann, haben wir im Artikel Gegengifte für SQL Injection bereits besprochen. Als wichtigste Waffe zur Validierung des Inputs stehen unter .NET (Überraschung!) Regular Expressions zur Verfügung - wer also in ASP RegEx gelernt hat, kann dieses Wissen unter .NET wieder einsetzen. Wer's noch nicht gemerkt hat: ich halte RegEx für eine der wichtigsten Techniken die ein Programmierer beherrschen sollte. Mit Inputvalidierung werden wir uns heute außer im obigen Absatz nicht weiter beschäftigen - statt dessen möchte ich Codebeispiele zeigen: zuallererst eines, das man sich als schlechtes Beispiel unbedingt immer vor Augen halten sollte, sowie ein weiteres, das man sich aus anderen Gründen merken sollte: weil man in Zukunft nur noch so programmieren sollte! So in Zukunft nicht mehrIch habe ein Beispiel nach alter Verfahrensweise geschrieben - der SQL String wird dynamisch zusammengebaut, was bei unzureichender Überprüfung der übergebenen Daten zur SQL Injection führt (jessas.aspx): <%@Page Language="C#" %> <%@Import Namespace="System.Data" %> <%@Import Namespace="System.Data.SqlClient" %> <% string strImagineAsQuerystring = "HANAR"; string strConn = "user id=restricted;password=uX98x00;initial catalog=northwind;" + "data source=WEBDEVSRV01;Connect Timeout=30"; SqlConnection scNWind = new SqlConnection(strConn); scNWind.Open(); SqlCommand cmd = new SqlCommand(); cmd.CommandText = "select sum(freight) from Orders " + " where CustomerId = '" + strImagineAsQuerystring + "'"; cmd.Connection = scNWind; object RetVal = cmd.ExecuteScalar(); Response.Write(RetVal.ToString()); cmd.Dispose(); scNWind.Close(); %> Ist die Variable strImagineAsQuerystring nicht genügend überprüft, so kann ein Hacker wie im Artikel SQL Injection beschrieben, ein beliebiges SQL Kommando gegen die Datenbank absetzen. Die Überprüfung (Inputvalidierung) sollte man also auf Fälle durchführen - und zwar am besten mit Regular Expressions, siehe dazu auch die Hinweise/Links im Artikel Gegengifte für SQL Injection. Aber ADO.NET hat noch ein zusätzliches "Zuckerl" für uns, das den Hahn für immer zudreht - und um einiges bequemer funktioniert als in ADO. Parametrisierte AbfragenVorhang auf für parametrisierte Abfragen, den "kleinen Bruder" (oder Schwester, falls man politisch korrekt sein möchte) von Stored Procedures. Wer keine Stored Procedures verwenden will oder kann, findet in parametrisierten Abfragen sicherlich eine probate "last line of defense" gegen SQL Injection. Somit ohne weitere Umschweife zu einem Beispiel (mitgenuss.aspx): <%@Page Language="C#" Debug="True" %> <%@Import Namespace="System.Data" %> <%@Import Namespace="System.Data.SqlClient" %> <% string strImagineAsQuerystring = "HANAR"; // uncomment line below to try SQL Injection (will fail) // strImagineAsQuerystring = "' DELETE Orders --"; string strConn = "user id=sa;password=;initial catalog=northwind;" + "data source=WEBDEVSRV01;Connect Timeout=30"; SqlConnection scNWind = new SqlConnection(strConn); scNWind.Open(); SqlCommand cmd = new SqlCommand(); cmd.CommandText = "select OrderId from Orders where CustomerId = @ParameterCustomerId"; SqlParameter param = cmd.Parameters.Add("@ParameterCustomerId", strImagineAsQuerystring); cmd.Connection = scNWind; SqlDataReader MySqlReader = cmd.ExecuteReader(); while (MySqlReader.Read()) { Response.Write(MySqlReader.GetInt32(0) + "<br>\r\n"); } MySqlReader.Close(); cmd.Dispose(); scNWind.Close(); %> Der richtig interessante Part ist der CommandText, also unser SQL Statement: cmd.CommandText = "select OrderId from Orders where CustomerId = @ParameterCustomerId"; Hier steht ab sofort ein Platzhalter, nicht einmal mehr Apostrophe, obwohl es sich um ein Textfeld handelt. Klarerweise muß man den Wert dieses Parameters vor der Ausführung bekanntgeben, dies geschieht so: SqlParameter param = cmd.Parameters.Add("@ParameterCustomerId", strImagineAsQuerystring); Im Prinzip funktioniert alles genau gleich wie bei Stored Procedures, und mehr zu Stored Procedures in ADO.NET bietet der Artikel Stored Procedures 101 in ADO.NET. Apropos Stored Procedures - es wäre an der Zeit, sich neben Regular Expressions auch mit diesen etwas näher auseinanderzusetzen. SchlußbemerkungSQL Injection verschwindet auch unter .NET nicht einfach magisch. Man muß nachhelfen, aber wenn man seine Applikation von vorne herein mit Blickpunkt Sicherheit plant und programmiert, ist es kein Problem. Download des CodesKlicken Sie hier, um den Download zu starten. Verwandte Artikel
Formularbasierte Authentifizierung in fünf Minuten 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.
©2000-2006 AspHeute.com |