Estamos tendo outra discussão aqui no trabalho sobre o uso de consultas sql parametrizadas em nosso código. Temos dois lados na discussão: eu e alguns outros que dizem que devemos sempre usar parâmetros para proteção contra injeções de sql e os outros caras que acham que não é necessário. Em vez disso, eles desejam substituir apóstrofos únicos por dois apóstrofos em todas as strings para evitar injeções de sql. Nossos bancos de dados estão todos executando Sql Server 2005 ou 2008 e nossa base de código está executando em .NET framework 2.0.
Deixe-me dar um exemplo simples em C #:
Eu quero que usemos isso:
string sql = "SELECT * FROM Users WHERE Name=@name";
SqlCommand getUser = new SqlCommand(sql, connection);
getUser.Parameters.AddWithValue("@name", userName);
//... blabla - do something here, this is safe
Enquanto os outros caras querem fazer isso:
string sql = "SELECT * FROM Users WHERE Name=" + SafeDBString(name);
SqlCommand getUser = new SqlCommand(sql, connection);
//... blabla - are we safe now?
Onde a função SafeDBString é definida da seguinte forma:
string SafeDBString(string inputValue)
{
return "'" + inputValue.Replace("'", "''") + "'";
}
Agora, enquanto usarmos SafeDBString em todos os valores de string em nossas consultas, devemos estar seguros. Certo?
Existem dois motivos para usar a função SafeDBString. Primeiro, é a maneira como tem sido feito desde a idade da pedra e, segundo, é mais fácil depurar as instruções sql, pois você vê a consulta exata que é executada no banco de dados.
Então. Minha dúvida é se realmente é suficiente usar a função SafeDBString para evitar ataques de injeção de sql. Tenho tentado encontrar exemplos de código que violem essa medida de segurança, mas não consigo encontrar nenhum exemplo disso.
Há alguém aí que pode quebrar isso? Como você faria?
EDITAR: Para resumir as respostas até agora:
- Ninguém encontrou uma maneira de contornar o SafeDBString no Sql Server 2005 ou 2008 ainda. Isso é bom, eu acho?
- Várias respostas indicaram que você obtém um ganho de desempenho ao usar consultas parametrizadas. O motivo é que os planos de consulta podem ser reutilizados.
- Também concordamos que o uso de consultas parametrizadas fornece um código mais legível e mais fácil de manter
- Além disso, é mais fácil sempre usar parâmetros do que usar várias versões de SafeDBString, strings para conversões de números e strings para conversões de datas.
- Usando parâmetros, você obtém conversão automática de tipo, algo que é especialmente útil quando estamos trabalhando com datas ou números decimais.
- E, finalmente: não tente fazer a segurança sozinho, como escreveu JulianR. Os fornecedores de banco de dados gastam muito tempo e dinheiro com segurança. Não há como fazermos melhor e não há razão para tentarmos fazer o trabalho deles.
Portanto, embora ninguém tenha conseguido quebrar a segurança simples da função SafeDBString, recebi muitos outros bons argumentos. Obrigado!