Pergunta

Eu estou usando C # e .NET 3.5. Eu preciso gerar e armazenar algumas T-SQL insert declarações que serão executados mais tarde em um servidor remoto.

Por exemplo, eu tenho um conjunto de funcionários:

new Employee[]
{
   new Employee { ID = 5, Name = "Frank Grimes" },
   new Employee { ID = 6, Name = "Tim O'Reilly" }
}

e eu preciso acabar com uma matriz de strings, como este:

"INSERT INTO Employees (id, name) VALUES (5, 'Frank Grimes')",
"INSERT INTO Employees (id, name) VALUES (6, 'Tim O''Reilly')"

Eu estou olhando para algum código que cria as instruções de inserção com String.Format, mas que não se sente bem. Eu considerei usando SqlCommand (esperando para fazer como este ), mas ele não oferece uma maneira de combinar o texto de comando com parâmetros.

É o suficiente apenas para substituir aspas simples e construir uma string?

string.Format("INSERT INTO Employees (id, name) VALUES ({0}, '{1}')",
    employee.ID,
    replaceQuotes(employee.Name)
    );

O que eu deveria estar preocupado com quando está fazendo isso? Os dados de origem é bastante seguro, mas eu não quero fazer muitas suposições.

EDIT: Só quero salientar que, neste caso, eu não tenho um SqlConnection ou alguma maneira de se conectar diretamente ao SQL Server. Esta aplicação em particular precisa gerar instruções SQL e fila-los para serem executados em outro lugar - caso contrário eu estaria usando SqlCommand.Parameters.AddWithValue ()

Foi útil?

Solução

Use parametrizado comandos. Passar os parâmetros juntamente com o servidor remoto, bem como, e conseguir que pôr em SQL Server, ainda mantendo a distinção entre o próprio SQL e os valores dos parâmetros.

Enquanto você nunca misturar dados tratar como código, você deve estar bem.

Outras dicas

Crie o seu objeto SqlCommand como assim:

SqlCommand cmd = new SqlCommand(
        "INSERT INTO Employees (id, name) VALUES (@id, @name)", conn);

SqlParameter param  = new SqlParameter();
param.ParameterName = "@id";
param.Value         = employee.ID;

cmd.Parameters.Add(param);

param  = new SqlParameter();
param.ParameterName = "@name";
param.Value         = employee.Name;

cmd.Parameters.Add(param);

cmd.ExecuteNonQuery();

Corrigir o seu substituir aspas funcionar desta forma:

void string replaceQuotes(string value) {
     string tmp = value;
     tmp = tmp.Replace("'", "''");
     return tmp;
}

Felicidades!

Hmm Concordo com todos os outros que você deve estar usando consultas parametrizadas e vai deixar por isso mesmo. Mas como é que você vai passar essas instruções SQL para o servidor remoto? Você tem algum tipo de serviço como um serviço web que irá aceitar e executar arbitrárias comandos SQL ou é o seu aplicativo cliente vai bater o DB diretamente?

Se o seu curso através de algum tipo de proxy, então não importa o quanto você higienizar seus dados no cliente, um hacker poderia simplesmente ignorar a sua aplicação e bateu o serviço. Caso em que fazer o que Cade recomenda e passar os dados como XML, por exemplo, ou qualquer formato que você escolher (JSON, Binary etc ..) Em seguida, construir o seu direito SQL antes de realmente executar o comando.

Para evitar a injecção, você precisa enviar os dados para o servidor remoto (talvez em XML) e, em seguida, no servidor remoto, os dados devem estar de volta convertidos em tipos de dados apropriados e utilizados em consultas parametrizadas ou procedimentos armazenados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top