0
votes

FromeSQL (): Bâtiment de la chaîne de requête à partir de la liste des chaînes pour éviter toute injection

Je construis une recherche SQL dans EF Core. Microsoft vous recommande de ne pas concéder une chaîne car elle laisse l'application vulnérable à l'injection SQL comme détaillé dans Microsoft Documentation: https://docs.microsoft.com/en-us/ef/core/Querying/raw-sql .

Toujours utiliser le paramétrage pour les requêtes SQL brutes: En plus de Validation de l'entrée utilisateur, utilisez toujours le paramétrage pour toutes les valeurs utilisées dans une requête / commande SQL brute. API qui acceptent une chaîne SQL brute telle que Detsql et ExécutesqlCommand permettent de passer des valeurs à transmettre comme paramètres. Surcharges de Fromeql et exécutesqlCommand qui acceptent FormattableString permet également d'utiliser la syntaxe d'interpolation de chaîne dans un manière qui aide à protéger contre les attaques d'injection SQL.

Si vous utilisez la concaténation de chaîne ou l'interpolation pour dynamiquement Construisez n'importe quelle partie de la chaîne de requête ou passez à une entrée utilisateur à déclarations ou procédures stockées pouvant exécuter ces entrées comme Dynamic SQL, alors vous êtes responsable de la validation de toute entrée à Protéger contre les attaques d'injection SQL.

Les informations stockées dans cette base de données ne sont pas sensibles, mais je ne voudrais évidemment pas quitter la base de données vulnérable.

J'ai une liste de paramètres paramètre SearchTerms < / Code> que j'ai besoin de itérer et de construire une requête basée sur cette liste.

Je vais et les cordes avec ma requête SQL, mais je ne peux que voir comment faire cela avec une concaténation. À l'heure actuelle, mon code ressemble à ceci. xxx

même si j'utilise l'interpolation, une validation supplémentaire suffirait-elle? Je manque quelque chose?

Y a-t-il une requête LINQ qui peut faire la même chose avec une liste?


4 commentaires

DeSQL a une surcharge qui vous permet de passer des paramètres. Pourquoi ne l'utilisez-vous pas?


Au fait, plusieurs et conditions sur le même champ. Vous devez probablement utiliser ou ici.


@Steve Comment puis-je ajouter les paramètres à la surcharge de FRTSQL en fonction d'une liste de la taille de changement?


Si vous passez plusieurs valeurs, avez-vous envisagé d'utiliser un paramètre de valorisation de la table? Si vous préférez ne pas utiliser de TVP, vous pouvez passer une liste délimitée et utiliser un séparateur de chaîne comme string_split .


4 Réponses :


-1
votes

Je recommanderais de regarder Linq si vous utilisez EF. Utilisation de SQL RAW SQL n'est pas une très bonne idée pour la sécurité et la performance. LINQ fournit une manière robuste d'effectuer des requêtes. Soyez prudent sur la façon dont vous écrivez vos requêtes alors que Linq peut tenter de les compliquer.

https://docs.microsoft.com/en-us/dotnet/cshaarp/programming-Guide/concepts/linq/ P>

Edit: P>

J'ai raté la dernière ligne de votre message. Désolé, les éléments suivants devraient vous aider à trouver sur la bonne voie: P>

for (var item in searchTerms) {
    query = query.Where(w => w.MySqlField.Contains(item.Value));
}


2 commentaires

J'aurais fait cela pour commencer, mais je voulais éviter un scénario où j'exécute une recherche à travers plusieurs itérations à laquelle je devrais m'assurer que les résultats sont distincts - il semble que des frais généraux supplémentaires inutiles. J'aimerais exécuter une seule requête s'il y a une manière possible.


Sans plus d'insite dans votre code, la seule aide que je peux vous offrir qu'il y aurait de conserver la requête comme une iquérissable avant d'exécuter ce forach (que je me rendais compte que j'ai oublié le chacun). Il ne traitera pas la requête jusqu'à ce que vous le converties ou de le forcer avec .tolist () ou quelle que soit votre méthode préférée. De cette façon, vous ne frappez que la base de données une fois. En ce qui concerne les entrées de requête distinctes, vous pouvez utiliser SearchTerms.Distinct () avec peu de temps réelle. Bien que vous souhaitiez regarder vos contributions pour voir pourquoi vous auriez des multiples ..



1
votes

Je ne peux pas le tester pour le moment, je vous le ferai savoir sur cette approche

List<string> ph = new List<string>();
int count = 0;
foreach(string s in searchTerm)
{
    ph.Add($"MySqlField LIKE '%{{{count}}}%'");
    count++;
}

if(count > 0)
    query = query + " WHERE " + string.Join(" OR ", ph);
var results = context.MySqlTable.FromSql(query, searchTerm.ToArray());


2 commentaires

Pas besoin de tester, je cherche seulement l'approche. Je peux tester seuls.


Il y a probablement quelque chose à réparer dans le% Wildcard et les citations simples. Maintenant, on dirait que nous construisons un texte littéral ici au lieu d'un espace réservé paramètre



1
votes

Il y a peu d'options:

  1. transmettez vos valeurs dans XML (ou JSON si vous utilisez le serveur SQL plus récent), puis écrivez la requête XML / JSON statique.

  2. Créez une table temporaire, insérez toutes les valeurs de recherche dans une table Temp, puis exécutez la requête statique.


2 commentaires

Le numéro 2 est clairement la bonne réponse à ce problème.


Option 3: Utilisez une recherche en texte intégral.



0
votes

Votre code doit être assez bon avec un peu de modification: xxx


2 commentaires

C'est exactement ce que je cherche en termes d'utilisation d'une liste / de tableau en tant que paramètre à chaîne. Pouvez-vous expliquer où 1 = 1 ?


@ Ce 1 = 1 est là comme critère "factice" afin que je puisse commencer à ajouter et ... à partir du début de la boucle.