J'écris une classe à utiliser dans le cadre d'un algorithme de modélisation beaucoup plus large. Ma partie fait l'analyse spatiale pour calculer les distances de certains points à d'autres points. Il existe une variété de conditions impliquant le nombre de distances retournées, les distances de coupure, etc.

Actuellement, la spécification du projet n'indique que des situations codées en dur. c'est-à-dire que "la fonction n ° 1 doit répertorier toutes les distances de l'ensemble de points A à l'ensemble de points B dans un rayon de 500 m. La fonction n ° 2 doit répertorier toutes les distances de l'ensemble de points C à l'ensemble de points D ..." et ainsi de suite.

Je ne veux pas coder ces paramètres en dur, pas plus que la personne qui développe la prochaine étape du modèle, car évidemment, elle aimerait modifier les paramètres ou éventuellement réutiliser l'algorithme dans d'autres projets où ils auront des conditions différentes .

Maintenant, le problème est que j'utilise psycopg2 pour ce faire. C'est la norme dans laquelle je travaille donc je n'ai pas le choix de m'en écarter. J'ai lu que c'est une très mauvaise idée d'exposer les paramètres qui seront mis dans les requêtes exécutées en tant que paramètres en raison de la raison évidente de l'injection SQL. Cependant, je pensais que psycopg2 nettoyait automatiquement l'entrée SQL. Je pense que le problème est d'utiliser la fonction AsIs.

La solution simple est simplement de le coder en dur comme spécifié dans le projet, mais cela me semble paresseux et bâclé. Je n'aime pas faire un travail paresseux et bâclé.

Est-il sûr de permettre à l'utilisateur de saisir des paramètres qui seront saisis dans une requête exécutée par psycopg2? Ou est-ce simplement l'utilisation de AsIs qui le rend dangereux? Si je voulais permettre à l'utilisateur de pouvoir entrer ces paramètres, dois-je prendre la responsabilité de santitiser les entrées, et si oui, y a-t-il un moyen rapide et facile de le faire, comme avec une autre bibliothèque python ou quelque chose?

9
wfgeo 16 juil. 2017 à 16:02

2 réponses

Meilleure réponse

Vous pouvez utiliser psycopg2.sql pour rédiger des requêtes dynamiques. Contrairement à AsIs, il vous protégera de l'injection SQL.

2
piro 21 juil. 2017 à 11:51

AsIs est dangereux, sauf si vous savez vraiment ce que vous faites. Vous pouvez l'utiliser pour des tests unitaires par exemple.

Passer des paramètres n'est pas si dangereux, tant que vous ne pré-formatez pas votre requête SQL. Jamais fait:

sql_query = 'SELECT * FROM {}'.format(user_input)
cur.execute(sql_query)

Puisque user_input pourrait être ';DROP DATABASE;' par exemple.

Au lieu de cela, faites:

sql_query = 'SELECT * FROM %s'
cur.execute(sql_query, (user_input,))

pyscopg2 nettoiera votre requête. En outre, vous pouvez pré-nettoyer les paramètres de votre code avec votre propre logique, si vous ne faites vraiment pas confiance à l'entrée de votre utilisateur.

Selon la documentation de psycopg2:

Avertissement Jamais, jamais, JAMAIS utiliser la concaténation de chaîne Python (+) ou l'interpolation de paramètres de chaîne (%) pour passer des variables à une chaîne de requête SQL. Pas même sous la menace d'une arme.

De plus, je ne laisserais jamais, jamais, mes utilisateurs me dire quelle table je devrais interroger. La logique (ou les routes) de votre application devrait vous le dire.

Concernant AsIs(), par documentation de psycopg2:

Asis () ... pour les objets dont la représentation sous forme de chaîne est déjà valide comme représentation SQL.

Donc, ne l'utilisez pas avec l'entrée de l'utilisateur.

13
Diego Mora Cespedes 16 juil. 2017 à 13:27