L’injection SQL est un vecteur d’attaque simple qui reste très courant aujourd’hui. La raison n’est que l’absence de patch pour la stupidité. Pourquoi dites-vous cela, prenons JAVA comme exemple pour illustrer :
Supposons qu’une table de ce type existe dans la base de données :
Ensuite, utilisez la table d’action JDBC :
Le code ci-dessus est souvent utilisé par certains développeurs. Imaginez une situation où le paramètre userId entrant est « 3 ; utilisateur de table de dépôt ; L’instruction SQL exécutée est la suivante :
Après la compilation et exécution de la base de données, la table utilisateur est supprimée. Voilà, une simple attaque d’injection SQL prend effet ! Cela s’explique par le fait que le code ci-dessus ne respecte pas les spécifications de programmation.
Lorsque nous programmons selon la spécification, l’injection SQL est inexistante. C’est aussi le casLa première façon d’éviter l’injection SQL : les instructions précompilées, le code est le suivant :
Pourquoi l’injection SQL n’existe-t-elle pas dans le code ci-dessus ? Parce que l’instruction précompilée est utilisée, celle-ci définira « select name from user where id= ? » L’instruction est compilée à l’avance pour qu’elle ne doive être remplacée que par les paramètres entrants lors de son exécution ? Les espaces réservés sont très bien. Dans le premier cas non conforme, le programme écrira une instruction SQL puis la compilera avec le contenu transmis par l’utilisateur, ce qui est précisément le problème.
En plus d’utiliser des instructions précompilées, il existe une seconde optionMoyens d’éviter les attaques par injection SQL : procédures stockées。 Une procédure stockée est un ensemble d’instructions SQL qui remplissent une fonction spécifique, compilées et stockées dans une base de données, et l’utilisateur peut l’exécuter en appelant une procédure stockée et en fournissant un paramètre (si la procédure stockée possède des paramètres), ce qui peut également éviter les attaques d’injection SQL
La procédure stockée correspondante dans le code ci-dessus est la suivante :
Bien sûr, les utilisateurs peuvent aussi effectuer une vérification de caractères sur le frontend, ce qui est aussi un moyen d’éviter l’injection SQL : par exemple, pour le paramètre userId ci-dessus, l’utilisateur vérifiera un point-virgule et une erreur sera affichée. Cependant, la raison la plus fondamentale est que les attaques d’injection SQL existent parce que les applications n’utilisent pas le moindre privilège lors de l’accès aux bases de données. Il semble que tout le monde utilise le compte racine pour accéder à la base de données.
Alors, comment MyBatis évite-t-il les attaques d’injection SQL ? Ou prenez l’utilisateur du tableau ci-dessus comme exemple : Disons que le fichier mapper est :
Les fichiers Java correspondants sont :
Vous pouvez voir que le paramètre d’entrée est userId de type String, lorsque nous passons userId="34 ; utilisateur de table de dépôt ; Ensuite, la déclaration imprimée se lit comme suit :
Peu importe l’identifiant utilisateur saisi, sa déclaration SQL est la suivante. Cela s’explique par le fait que mybatis utilise des instructions précompilées dans l’implémentation sous-jacente. Lorsque la base de données exécute cette instruction, elle utilise directement l’instruction précompilée puis remplace le placeholder par l’userID qui passe ? Va juste courir. Remplacer d’abord les espaces réservés ? Le processus de compilation est réalisé, il n’y a donc aucune place pour que l’injection SQL survive.
Alors, comment MyBatis fait-il la précompilation SQL ? En fait, la classe PreparedStatement est utilisée en bas du cadre. La classe PreparedStaement évite non seulement l’injection SQL, mais permet aussi de gagner (N-1) temps de compilation lorsque la même instruction SQL est exécutée N fois, améliorant ainsi l’efficacité.
Si vous modifiez l’énoncé ci-dessus pour :
Lorsque nous entrons userId="34 ; utilisateur de table de dépôt ; Ensuite, la déclaration imprimée se lit comme suit :
À ce stade, mybatis n’utilise pas d’instructions précompilées, il assemble d’abord les chaînes puis effectue la compilation, ce qui est exactement le cas de l’injection SQL.
Ainsi, lors de l’écriture des instructions de mappage mybatis, essayez d’utiliser le format « #{xxx} ». Si vous devez utiliser des paramètres comme « ${xxx} », vous devez les filtrer manuellement pour éviter les attaques d’injection SQL.
|