Pergunta

.NET, Java e outras APIs de banco de dados de alto nível em várias linguagens geralmente fornecem técnicas conhecidas como instruções preparadas e ligação de parâmetros, em vez de enviar comandos de texto simples para o servidor de banco de dados.O que eu gostaria de saber é o que acontece quando você executa uma instrução como esta:

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

Eu sei que esta é uma prática recomendada.Os ataques de injeção de SQL são minimizados dessa forma.Mas o que exatamente acontece nos bastidores quando você executa essas instruções?O resultado final ainda é uma string SQL segura?Se não, qual é o resultado final?E isso é suficiente para evitar ataques de injeção de SQL?

Foi útil?

Solução

A página de manual do MySQL nas instruções preparadas fornece muitas informações (que devem se aplicar a qualquer outro RDBMS).

Basicamente, sua instrução é analisada e processada antecipadamente, e os parâmetros são enviados separadamente em vez de serem manipulados junto com o código SQL.Isso elimina ataques de injeção de SQL porque o SQL é analisado antes mesmo de os parâmetros serem definidos.

Outras dicas

em termos leigos:se uma instrução preparada for enviada, o banco de dados usará um plano, se estiver disponível, não será necessário recriar um plano toda vez que esta consulta for enviada, mas apenas os valores dos parâmetros foram alterados.isso é muito semelhante ao modo como os procs funcionam, o benefício adicional dos procs é que você pode dar permissão apenas por meio de procs e não para as tabelas subjacentes

Se você estiver usando MS SQL, carregue o criador de perfil e verá quais instruções SQL são geradas quando você usa consultas parametrizadas.Aqui está um exemplo (estou usando o Enterprise Libary 3.1, mas os resultados são os mesmos usando SqlParameters diretamente) no 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);
}

Isso gera:

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

Você também pode ver aqui, se as aspas foram passadas como parâmetros, elas serão escapadas de acordo:

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top