2008-08-18 15 views
6

.NET, Java y otras API de bases de datos de alto nivel en varios idiomas a menudo proporcionan técnicas conocidas como declaraciones preparadas y enlace de parámetros en lugar de enviar comandos de texto plano al servidor de la base de datos. Lo que me gustaría saber es lo que sucede cuando se ejecuta una sentencia como esta:Encuadernación de parámetros: ¿Qué sucede debajo del capó?

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

Sé que esto es una buena práctica. Los ataques de inyección SQL se minimizan de esta manera. Pero, ¿qué sucede exactamente bajo el capó cuando ejecutas estas declaraciones? ¿El resultado final sigue siendo una cadena SQL segura? Si no, ¿cuál es el resultado final? ¿Y esto es suficiente para evitar los ataques de inyección SQL?

Respuesta

5

The MySQL manual page en declaraciones preparadas proporciona mucha información (que debe aplicarse a cualquier otro RDBMS).

Básicamente, su extracto se analiza y procesa antes de tiempo, y los parámetros se envían por separado en lugar de manipularse junto con el código SQL. Esto elimina los ataques de inyección SQL porque el SQL se analiza antes de que los parámetros estén configurados.

0

Si está utilizando MS SQL, cargue el generador de perfiles y verá qué sentencias SQL se generan cuando utiliza consultas parametrizadas. He aquí un ejemplo (estoy usando Empresa Libary 3.1, pero los resultados son los mismos que utilizan SqlParameters directamente) en 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); 
} 

Esto genera:

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 

También puede ver aquí, si se pasaron personajes como parámetros de cotización, que se escaparon en consecuencia:

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

en términos simples: si se envía una declaración preparada entonces la base de datos se utiliza un plan si está disponible, no lo hace no tiene que volver a crear un plan cada vez que se envía esta consulta, pero solo han cambiado los valores de los parámetros. esto es muy similar a cómo funcionan los procs, el beneficio adicional con procs es que usted puede dar permiso a través de procs solamente y no a las tablas subyacentes en absoluto

Cuestiones relacionadas