2008-08-18 13 views
6

.NET, Java und andere High-Level-Datenbank-APIs in verschiedenen Sprachen bieten häufig Techniken, die als vorbereitete Anweisungen und Parameterbindung bekannt sind, im Gegensatz zum Senden von Nur-Text-Befehlen an den Datenbankserver. Was ich möchte, ist wissen, was passiert, wenn Sie eine Anweisung wie folgt auszuführen:Parameterbindung: Was passiert unter der Haube?

SqlCommand cmd = new SqlCommand("GetMemberByID"); 
cmd.CommandType = CommandType.StoredProcedure; 
SqlParameter param = new SqlParameter("@ID", memberID); 
para.DbType = DbType.Integer; 
cmd.Parameters.Add(param); 

Ich weiß, das ist eine bewährte Methode. SQL-Injection-Angriffe werden auf diese Weise minimiert. Aber was genau passiert unter der Haube, wenn Sie diese Anweisungen ausführen? Ist das Endergebnis noch eine SQL-sichere Zeichenfolge? Wenn nicht, was ist das Endergebnis? Und ist das genug, um SQL-Injection-Angriffe zu verhindern?

Antwort

5

The MySQL manual page über vorbereitete Anweisungen bietet viele Informationen (die für alle anderen RDBMS gelten sollten).

Grundsätzlich wird Ihre Anweisung im Voraus analysiert und verarbeitet, und die Parameter werden separat gesendet, anstatt mit dem SQL-Code behandelt zu werden. Dadurch werden SQL-Injection-Angriffe vermieden, da SQL analysiert wird, bevor die Parameter festgelegt werden.

0

Wenn Sie MS SQL verwenden, laden Sie den Profiler und Sie werden sehen, welche SQL-Anweisungen generiert werden, wenn Sie parametrisierte Abfragen verwenden. Hier ist ein Beispiel (ich bin mit Enterprise Libary 3.1, aber die Ergebnisse sind der gleiche mit SqlParameters direkt) gegen SQL Server 2005:

string sql = "SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did"; 
Database db = DatabaseFactory.CreateDatabase(); 
using(DbCommand cmd = db.GetSqlStringCommand(sql)) 
{ 
    db.AddInParameter(cmd, "DomName", DbType.String, "xxxxx.net"); 
    db.AddInParameter(cmd, "Did", DbType.Int32, 500204); 

    DataSet ds = db.ExecuteDataSet(cmd); 
} 

Dies erzeugt:

exec sp[underscore]executesql N'SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did', 
    N'@DomName nvarchar(9), 
    @Did int', 
    @DomName=N'xxxxx.net', 
    @Did=500204 

Sie können hier sehen, wenn Anführungszeichen Zeichen als Parameter übergeben wurden, sind sie entsprechend entkommen:

db.AddInParameter(cmd, "DomName", DbType.String, "'xxxxx.net"); 

exec sp[underscore]executesql N'SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did', 
    N'@DomName nvarchar(10), 
    @Did int', 
    @DomName=N'''xxxxx.net', 
    @Did=500204 
0

in Laiebezeichnungen: wenn eine vorbereitete Anweisung gesendet wird, dann wird die DB einen Plan verwenden, wenn es verfügbar ist, es nicht nicht müssen jedes Mal, wenn diese Abfrage gesendet wird, einen Plan neu erstellen, aber nur die Werte der Parameter haben sich geändert. Dies ist sehr ähnlich wie procs funktioniert, der zusätzliche Vorteil mit Procs ist, dass Sie nur über Procs und nicht über die zugrunde liegenden Tabellen eine Berechtigung geben können