Domanda

Sto usando C # e .NET 3.5. Devo generare e archiviare alcune istruzioni di inserimento T-SQL che verranno eseguite in seguito su un server remoto.

Ad esempio, ho una serie di dipendenti:

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

e devo finire con una serie di stringhe, come questa:

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

Sto guardando un po 'di codice che crea le istruzioni insert con String.Format, ma ciò non sembra corretto. Ho considerato l'utilizzo di SqlCommand (sperando di fare qualcosa di simile questo ), ma non offre un modo per combinare il testo del comando con i parametri.

È sufficiente sostituire solo virgolette singole e creare una stringa?

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

Di cosa dovrei preoccuparmi quando faccio questo? I dati di origine sono abbastanza sicuri, ma non voglio fare troppe ipotesi.

EDIT: voglio solo sottolineare che in questo caso, non ho un SqlConnection o alcun modo per connettermi direttamente a SQL Server. Questa particolare app deve generare istruzioni sql e metterle in coda per essere eseguite altrove, altrimenti userei SqlCommand.Parameters.AddWithValue ()

È stato utile?

Soluzione

Utilizza comandi con parametri. Passa i parametri anche al tuo server remoto e ottieni che li chiami in SQL Server, mantenendo comunque la distinzione tra lo stesso SQL e i valori dei parametri.

Finché non mescoli mai i dati di trattamento come codice, dovresti essere a posto.

Altri suggerimenti

Crea il tuo oggetto SqlCommand in questo modo:

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();

Correggi la funzione di sostituzione delle virgolette in questo modo:

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

Cheers!

Hmm Sono d'accordo con tutti gli altri sul fatto che dovresti usare query con parametri e lo lascerò. Ma come hai intenzione di passare queste istruzioni sql al tuo server remoto? Hai qualche tipo di servizio come un servizio web che accetterà ed eseguirà comandi SQL arbitrari o la tua app client colpirà direttamente il DB?

Se stai attraversando una sorta di proxy, non importa quanto i tuoi dati vengano disinfettati sul client, un hacker potrebbe semplicemente bypassare la tua app e accedere al servizio. Nel qual caso fai ciò che Cade consiglia e passa i dati come XML, ad esempio o in qualsiasi formato tu scelga (JSON, Binary ecc.) Quindi costruisci il tuo SQL subito prima di eseguire effettivamente il comando.

Per evitare l'iniezione, è necessario spedire i dati al server remoto (forse in XML) e quindi sul server remoto, i dati devono essere riconvertiti in tipi di dati appropriati e utilizzati in query con parametri o processi memorizzati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top