Question

J'utilise C # et .NET 3.5. J'ai besoin de générer et de stocker des instructions d'insertion T-SQL qui seront exécutées ultérieurement sur un serveur distant.

Par exemple, j'ai un tableau d'employés:

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

et je dois me retrouver avec un tableau de chaînes, comme ceci:

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

Je regarde un code qui crée les instructions d'insertion avec String.Format, mais cela ne semble pas correct. J'ai envisagé d'utiliser SqlCommand (en espérant faire quelque chose comme ), mais cela ne permet pas de combiner le texte de la commande avec des paramètres.

Est-ce suffisant de remplacer les guillemets simples et de construire une chaîne?

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

De quoi devrais-je m'inquiéter lorsque je fais cela? Les données source sont relativement sûres, mais je ne veux pas formuler trop d'hypothèses.

EDIT: Je tiens simplement à souligner que dans ce cas, je n’ai pas de connecteur SqlConnection ni de moyen de se connecter directement à SQL Server. Cette application particulière doit générer des instructions SQL et les mettre en file d'attente pour pouvoir les exécuter ailleurs. Sinon, j'utiliserais SqlCommand.Parameters.AddWithValue ()

Était-ce utile?

La solution

Utilisez des commandes paramétrées. Transférez également les paramètres sur votre serveur distant et faites-les appeler dans SQL Server, tout en maintenant la distinction entre SQL et les valeurs de paramètre.

Tant que vous ne mélangez jamais les données de traitement avec du code, tout devrait bien se passer.

Autres conseils

Créez votre objet SqlCommand comme suit:

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

Corrigez vos citations de remplacement de cette manière:

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

Salut!

Hmm, je suis d’accord avec tout le monde pour dire que vous devriez utiliser des requêtes paramétrées et vous en resterez là. Mais comment allez-vous transmettre ces instructions SQL à votre serveur distant? Avez-vous un type de service tel qu'un service Web qui acceptera et exécutera des commandes Sql arbitraires ou votre application client va-t-elle accéder directement à la base de données?

Si vous utilisez une sorte de proxy, quel que soit le degré de désinfection de vos données sur le client, un pirate informatique pourrait simplement contourner votre application et accéder au service. Dans ce cas, suivez les recommandations de Cade et transmettez les données au format XML, par exemple, ou au format de votre choix (JSON, Binaire, etc.), puis créez votre code SQL juste avant de lancer la commande.

Pour éviter toute injection, vous devez envoyer les données au serveur distant (éventuellement en XML), puis sur le serveur distant. Les données doivent être reconverties en types de données appropriés et utilisées dans des requêtes paramétrées ou des procédures stockées.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top