Question:
Bonnes pratiques pour empêcher l'injection SQL?
Mark Davidson
2010-12-21 01:56:34 UTC
view on stackexchange narkive permalink

L'injection SQL est toujours un sujet brûlant, en particulier en matière de sécurité Web. À cet égard, je suis intéressé par les étapes à suivre pour empêcher l'injection SQL dans une application Web? En plus de ces étapes normales, y a-t-il autre chose que les gens font au-delà de la normale pour l'empêcher?

Sept réponses:
#1
+19
Chris Dale
2010-12-21 19:41:49 UTC
view on stackexchange narkive permalink

Déjà de très bonnes réponses à cette question, mais j'aimerais en mentionner quelques-unes:

  • Codage sécurisé (déjà mentionné par beaucoup)
    • Échapper à l'utilisateur input
    • Requêtes paramétrées (instructions préparées, requêtes prédéfinies où vous ne liez que des variables)
    • Code défensif
  • Surveillance des attaques
    • Système de détection d'intrusion réseau (NIDS)
    • Système de détection d'intrusion hôte (HIDS)
    • Système de détection d'intrusion d'application (AppIDS)
  • Bloquer les attaques
    • Pare-feu d'application
    • Pare-feu de base de données
    • Pare-feu d'application Web
      • Apache ModSecurity
      • Cisco Application Velocity System (AVS)
  • Sonder les vulnérabilités
    • Test d'injection de boîte noire automatisée
    • Statique analyse du code source
    • Test de pénétration manuel

Ceci est uniquement à des fins de prévention et je n'ai pas pris durcissement du serveur sql en compte. Il existe cependant de nombreuses similitudes.

Des défenses supplémentaires au cas où vous seriez déjà vulnérable à l'injection seraient:

  • Exécuter votre application avec le moins de subventions nécessaires
    • Accorder spécifiquement uniquement l'accès à la base de données et aux tables dont vous avez besoin
    • Assurez-vous de n'accorder que le privilège dont il a besoin (généralement sélectionner, insérer, mettre à jour)
+1, très bonne réponse. Un commentaire, cependant, a écrit votre dernier paragraphe - il vaut mieux ne pas accorder * aucun * accès directement sur les tables, à la place en utilisant des procédures stockées et en n'accordant l'accès qu'à elles.
#2
+16
Weber
2010-12-21 02:02:13 UTC
view on stackexchange narkive permalink

Instructions préparées, requêtes paramétrées, échappant à toutes les entrées utilisateur, pour un bon début, voir http://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet.

excellent lien. Toute chance de faire apparaître les points clés dans le corps de votre réponse - cela permet à quelqu'un de trouver plus facilement du contenu et améliore également l'indexation de cette question dans les moteurs de recherche.
Je suis d'accord avec @Rory - pouvez-vous mettre plus d'informations dans la réponse? Surtout une référence aux procs stockés - personne d'autre n'a mentionné cela, je vois ...
Les procédures stockées @AviD: ** sont ** un type spécifique de déclaration préparée
@symcbean - Je suppose que sémantiquement c'est vrai, mais typiquement «déclaration préparée» fait référence dans l'application, par opposition à dans la base de données.
#3
+10
Justin Clarke
2010-12-21 16:53:44 UTC
view on stackexchange narkive permalink

La principale défense est de n'utiliser que des API qui échappent en toute sécurité aux requêtes de base de données - on les appelle généralement des instructions paramétrées ou préparées. Celles-ci ne peuvent pas être utilisées dans tous les cas (par exemple lorsqu'un identifiant SQL tel que le nom de la table ou de la colonne est fourni au moment de l'exécution), mais c'est la meilleure approche dans la mesure du possible (la majorité des cas).

Remarque - cela peut conduire à l'insertion de données nuisibles dans la base de données, alors soyez conscient de cela lorsque vous utilisez ces données ailleurs dans l'application

La deuxième défense consiste à adopter une approche de fuite . Il s'agit de l'approche «remplacer un guillemet simple par deux guillemets». Si vous devez procéder de cette manière, vous devez échapper à chaque caractère potentiellement dangereux , ce qui signifie plus que des guillemets simples dans certains cas. Je vous conseillerais d'utiliser une bibliothèque de niveau supérieur telle que OWASP ESAPI si possible pour le faire pour vous, ou de lire attentivement la feuille de triche d'injection SQL OWASP (référencée ci-dessus).

#4
+9
bretik
2010-12-21 17:07:42 UTC
view on stackexchange narkive permalink

La principale étape pour protéger l'application Web contre l'injection SQL est de nettoyer correctement tout utilisateur. input (en particulier l'entrée utilisée dans les requêtes SQL). Dans certains langages / frameworks, il existe des méthodes standard pour gérer ces valeurs - par exemple en utilisant des requêtes paramétrées au lieu de composer la requête en joignant des valeurs de chaîne.

#5
+4
anonymous
2010-12-21 02:36:59 UTC
view on stackexchange narkive permalink

Du côté des développeurs Web, il faut attirer l'attention sur ce que Weber a déjà mentionné.

De plus, un pare-feu de base de données pourrait être mis en place, comme GreenSQL: http://www.greensql.net/. Cela fonctionne comme un proxy entre votre application et l'entrée utilisateur, surveille ce qui doit être transmis, etc. Cependant, cela entraîne un temps de réponse accru.

Cool - jamais entendu parler de greenSQL auparavant.
#6
+4
Kim Stacks
2011-01-18 22:19:28 UTC
view on stackexchange narkive permalink

J'enseigne la sécurité informatique dans les écoles polytechniques. Souvent, pour les étudiants, ils ont une certaine confusion sur les termes utilisés pour l'injection SQL, alors laissez-moi essayer de clarifier.

Dans le contexte d'une application Web comme Facebook,

L'injection SQL se produit lorsque le l'utilisateur Web normal entre le code SQL dans les champs de données Par exemple,

  'OR' 1 '=' 1 dans les zones de texte d'un formulaire de connexion.  

La meilleure personne pour empêcher l'injection SQL, c'est le développeur Web, alias la personne chargée d'écrire le code de l'application Web pour lire / écrire des données dans la base de données.

Le moyen le plus simple d'empêcher l'injection SQL par le développeur Web est d'utiliser requêtes paramétrées.

Les instructions préparées et les requêtes paramétrées signifient la même chose.

J'utiliserai les requêtes paramétrées à partir de maintenant.

Les requêtes paramétrées se réfèrent à la manière dont le code SQL est défini pour la première fois, puis les données sont placées dans les paramètres appropriés.

Par exemple dans .Net

  Mettre à jour le jeu ʻusers` set ` name` = @name où ʻid` = @id  

les paramètres @name et @id sont les données. Le reste est le code SQL.

Gardez à l'esprit que les requêtes paramétrées sont généralement mais pas toujours effectuées au niveau du code de l'application Web.

Il y a 2 façons d'écrire des requêtes paramétrées.

  1. Dans le code de l'application Web en fonction de la langue utilisée
  2. Dans la base de données utilisant des procédures stockées

Donc dans un certain sens, oui , les procédures stockées sont une forme de requêtes paramétrées.

Il existe d'autres moyens d'empêcher l'injection SQL en échappant des caractères spéciaux comme des guillemets simples. Par exemple, en PHP, vous pouvez utiliser mysql_real_escape_string qui met essentiellement des barres obliques avant les guillemets simples.

Ce n'est pas idéal à cause de problèmes avec% et soulignement pour l'opérateur LIKE dans certaines bases de données comme MySQL. voir ce pdf pour plus de détails.

Pour faire court, toutes les options suggérées concernent la désinfection (nettoyage) des entrées utilisateur pour nettoyer le code SQL.

Le meilleur moyen est d'utiliser des requêtes paramétrées en fonction du langage de programmation utilisé.

Fin de l'histoire.

#7
+3
yfeldblum
2011-01-19 08:22:05 UTC
view on stackexchange narkive permalink

Utilisez des API d'accès aux données décentes qui permettent de faire facilement ce qu'il faut, en toute sécurité.

Voici ActiveRecord v3:

  # basic usage @ user = User. où (: username = > '[email protected]'). first # avec un fragment de chaîne SQL, mais en utilisant des paramètres @ projects = @ user.projects.where ('status =?', params [: status])  


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 2.0 sous laquelle il est distribué.
Loading...