Maison >base de données >tutoriel mysql >mysql avancé (vingt-quatre) résumé des méthodes pour se défendre contre l'injection SQL
Cet article explique principalement les méthodes de défense contre l'injection SQL, présente ce qu'est l'injection, quelle est la raison de l'injection et comment se défendre contre cela. Les amis peuvent s'y référer.
L'injection SQL est une forme d'attaque très dangereuse. Même si les dégâts sont importants, la défense est bien moins difficile que le XSS.
L'injection SQL peut être trouvée à l'adresse : http://www.php.cn/
La raison pour laquelle la vulnérabilité d'injection SQL existe est de Paramètres SQL d'épissage. Autrement dit, les paramètres de requête utilisés pour la saisie sont directement intégrés à l'instruction SQL, ce qui entraîne des vulnérabilités d'injection SQL.
Nous voyons : select id ,no from user Where id=2;
Si l'instruction est obtenue en épissant des chaînes SQL, par exemple : String sql = "select id,no from user Where id=" id;
L'identifiant est un paramètre saisi par l'utilisateur Ensuite, si l'utilisateur saisit 2, alors nous pouvons voir une donnée trouvée ci-dessus. Si l'utilisateur saisit 2 ou 1=1, une attaque par injection SQL sera effectuée.
Ensuite, vous pouvez voir que l'instruction ci-dessus (select id,no from user which id=2 or 1=1;) a trouvé tous les enregistrements de la table user.
Il s'agit d'une injection SQL typique.
Regardez une autre colonne :
On voit que la table sqlinject peut être supprimée directement via sql injection ! Les dangers sont visibles !
La raison de l'injection SQL est, en apparence, parce que les chaînes sont épissées pour former des instructions SQL et des instructions SQL. ne sont pas précompilés et liés par des variables fixes.
Mais la raison la plus profonde est que la chaîne saisie par l'utilisateur est exécutée comme une "instruction SQL".
Par exemple, la chaîne ci-dessus sql = "select id,no from userwhere id=" id;
Nous espérons que la valeur de l'identifiant saisie par l'utilisateur n'est transmise que comme une valeur littérale de chaîne La base de données s'exécute, mais lorsque 2 ou 1=1 est entré, ou 1=1 n'est pas utilisé comme valeur littérale de Where id=, mais est exécuté comme une instruction SQL. Son essence est donc d’exécuter les données saisies par l’utilisateur sous forme de commande.
1> Fondamentalement, tout le monde sait que l'utilisation d'instructions SQL pour précompiler et lier des variables est le meilleur moyen de se défendre contre l'injection SQL. Mais toutes les raisons sous-jacentes ne sont pas comprises.
String sql = "select id, no from userwhere id=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, id);
ps.executeQuery();
Comme indiqué ci-dessus, il s'agit d'une utilisation typique de la précompilation d'instructions SQL et des variables de liaison. Pourquoi cela peut-il empêcher l’injection SQL ?
La raison est la suivante : en utilisant PreparedStatement, l'instruction SQL : "select id, no from user which id=?" sera pré-compilée, c'est-à-dire que le moteur SQL effectuera une analyse syntaxique à l'avance et générera un arbre syntaxique. Générez un plan d'exécution, c'est-à-dire que les paramètres que vous entrez plus tard, peu importe ce que vous entrez, n'affecteront pas la structure grammaticale de l'instruction SQL, car l'analyse grammaticale est terminée et l'analyse grammaticale analyse principalement SQL. commandes, telles que select ,from ,where ,et, ou ,order by etc. Ainsi, même si vous entrez ces commandes SQL plus tard, elles ne seront pas exécutées en tant que commandes SQL, car l'exécution de ces commandes SQL doit d'abord passer l'analyse syntaxique et générer un plan d'exécution. Maintenant que l'analyse syntaxique est terminée, elle a été précompilée. . , alors les paramètres saisis ultérieurement sont absolument impossibles à exécuter en tant que commandes SQL et ne seront traités que comme des paramètres littéraux de chaîne. Par conséquent, la précompilation des instructions SQL peut empêcher l’injection SQL.
2>Cependant, tous les scénarios ne peuvent pas utiliser la précompilation des instructions SQL. Certains scénarios doivent utiliser l'épissage de chaînes. À l'heure actuelle, nous vérifions strictement le type de données des paramètres et nous pouvons également utiliser certaines fonctions de sécurité pour l'injection SQL.
Par exemple, String sql = "select id,no from userwhere id=" id;
Lors de la réception des paramètres saisis par l'utilisateur, nous vérifions strictement l'identifiant, qui ne peut être que de tapez int. Des situations complexes peuvent être déterminées à l'aide d'expressions régulières. Cela peut également empêcher l'injection SQL.
Utilisation de fonctions sécurisées, telles que :
MySQLCodec codec = new MySQLCodec(Mode.STANDARD);
name = ESAPI.encoder().encodeForSQL(codec, name ) ;
String sql = "select id,no from userwhere name=" name;
ESAPI.encoder().encodeForSQL(codec, name)
Cette fonction encodera certains caractères spéciaux contenus dans le nom afin que le moteur SQL ne traite pas la chaîne du nom comme une commande SQL pour l'analyse syntaxique.
Dans les projets réels, nous utilisons généralement divers frameworks, tels que ibatis, mybatis, hibernate, etc. Ils sont généralement précompilés par défaut en SQL. Pour ibatis/mybatis, si vous utilisez le formulaire #{name}, alors c'est SQL précompilé. Si vous utilisez ${name}, ce n'est pas SQL précompilé.
Ce qui précède est un résumé des méthodes de défense contre les injections SQL. J'espère que cela sera utile pour les études futures de chacun.
C'est it MySQL Advanced (24) Résumé des méthodes de défense contre l'injection SQL Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !