Ho una tabella Project
con due colonne - ProjectId
e ProjectName
- e sto scrivendo una funzione che costruisce ed esegue un SqlCommand
per interrogare il database per gli ID di un Progetto con un nome specifico. Questo comando funziona, ma è vulnerabile a SQL Injection:Perché String.Format funziona ma SqlCommand.Parameters.Add non?
string sqlCommand = String.Format("SELECT {0} FROM {1} WHERE {2} = {3}",
attributeParam, tableParam, idParam, surroundWithSingleQuotes(idValue));
SqlCommand command = new SqlCommand(sqlCommand, sqlDbConnection);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
DataTable attributes = new DataTable();
adapter.Fill(attributes);
...
}
attributeParam
, tableParam
, idParam
, e idValue
sono tutte le stringhe. Ad esempio, potrebbero essere "ProjectId"
, "Project"
, "ProjectName"
e "MyFirstProject"
, rispettivamente. surroundWithSingleQuotes
circonda una stringa con ''
, quindi surroundWithSingleQuotes(idValue) == "'MyFirstProject'"
. Sto cercando di scrivere questa funzione nel modo più generale possibile in quanto potrei voler ottenere tutto un attributo dato da una tabella in futuro.
Anche se quanto sopra String.Format funziona, questo non lo fa:
string sqlCommand = String.Format("SELECT @attributeparam FROM {0} WHERE " +
"@idparam = @idvalue", tableParam);
command.Parameters.Add(new SqlParameter("@attributeparam", attributeParam));
command.Parameters.Add(new SqlParameter("@idparam", idParam));
command.Parameters.Add(new SqlParameter("@idvalue",
surroundWithSingleQuotes(idValue)));
SqlCommand command = new SqlCommand(sqlCommand, sqlDbConnection);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
DataTable attributes = new DataTable();
adapter.Fill(attributes);
...
}
io non so perché. Non ricevo alcun messaggio di errore, ma quando riempio il mio DataTable
utilizzando un SqlDataAdapter
, il DataTable non contiene nulla. Qui ci sono diversi approcci che ho preso, senza alcun risultato:
- seguito this answer e Microsoft's documentation, utilizzando
AddWithValue
o utilizzandoParameters.Add
eSqlParameter.Value
. - Sostituire in modo selettivo
{0}
,{1}
,{2}
e{3}
inString.Format
con il valore effettivo o la stringa di parametro.
In altri punti del mio codice, ho utilizzato le query parametrizzate (anche se con un solo parametro) senza problemi.
Gli unici parametri del pezzo possono essere sostituiti direttamente '{3}'. –
Non è possibile utilizzare un parametro per il nome di una colonna. Dovrai comunque usare 'string.Format' per questo, proprio come per il nome della tabella. – juharr