Durante os treinamentos que ministro, principalmente no curso de ADO.NET (2389) eu sempre oriento o pessoal a utilizar firmemente os Parameters ao invés de utilizar queries concatenadas com valores que são passados via formulários, QueryStrings, ou qualquer outra forma onde é o usuário que informa os dados.
Mas é necessário uma atenção especial quando se utiliza queries dinâmicas dentro do SQL Server. Mesmo utilizando parâmetros pois, neste caso, nem mesmo os parâmetros conseguem evitar o SQL Attack. É muito comum ver o pessoal utilizando essa técnica (eu também já utilizei) para suprir algumas limitações que existem com o SQL Server 2000 e que melhorou no 2005. Imaginem a Stored Procedure abaixo:
CREATE PROCEDURE RecuperaUsuarios
@Nome As Varchar(50) AS
DECLARE @Query As Varchar(1000)
SET @Query = ‘SELECT * FROM Usuarios WHERE Nome = ”’ + @Nome + ””
EXEC(@Query)
E agora o código .NET:
SqlCommand cmd = new SqlCommand(“RecuperaUsuarios”, conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter(“@Nome”, SqlDbType.VarChar);
param.Value = “‘; TRUNCATE TABLE Usuarios–“;
cmd.Parameters.Add(param);
Reparem que estou fixando a propriedade Value do objeto SqlParameter, mas o valor poderia ser proveniente de algum formulário que o usuário digitasse. Ao executar esse código, digam adeus aos seus registros.
Mas é importante dizer que muito se utiliza essa técnica (queries dinâmicas) quando utilizamos SQL Server 2000 (e que foi melhorado no 2005) e precisamos passar para a Stored Procedure a quantidade (TOP) de registros que queremos recuperar ou até mesmo quando precisamos efetuar uma paginação de resultados.
Para evitar problemas deste tipo precisamos ter como premissa que tudo que o usuário informa para a aplicação é extremamente perigoso. Isso nos levará a validar todas as informações, tanto do lado do cliente, quando do servidor, ou como fazem alguns bancos: só do lado do servidor. E quando eu digo validação, me refiro a tamanho, range, formato e tipo.