2009-07-20 5 views
7

Je travaille avec une équipe de développeurs sur un site web. Le site utilisera des classes. Je suis en charge de la création de la couche d'accès aux données pour les classes. Il est entendu que toute saisie de l'utilisateur sera échappée lors de la récupération (à partir de la poste ou obtenir). Ayant peu de contrôle sur le niveau d'entrée (à moins que j'examine personnellement le code de tout le monde), j'ai pensé que ce serait cool de m'enfuir de mon côté aussi (juste avant que ça ne frappe la base de données). Le problème est que je ne sais pas comment utiliser mysql_real_escape_string sans ajouter encore plus de barres obliques.Echapper seulement ce qui est nécessaire, est-ce possible?

Étant donné que l'entrée de l'utilisateur peut très bien contenir une barre oblique, je ne peux pas vérifier s'il y a des barres obliques. Je pourrais peut-être vérifier toutes les choses qui doivent s'échapper et m'assurer qu'elles ont une barre oblique devant elles, mais cela ne semble pas être la meilleure façon de le faire.

Des suggestions?

Répondre

7

Avez-vous considéré et non d'échapper les données jusqu'à ce qu'il touche la couche d'accès aux données? Je demande, parce que leur quelques avertissements relatifs à l'approche de votre équipe prend:

  • Si vous devez afficher des données de formulaire à l'utilisateur (par exemple, pour réafficher le formulaire avec un message d'erreur, car une validation a échoué), vous besoin de dés-échapper les données (car ' n'est pas spécial au HTML), puis ré-échapper les données (car < est spécial). Si vous devez afficher des données de formulaire à l'utilisateur extraites de la base de données, vous ne devez pas faire cette étape d'échappement (car cela a été fait par la base de données, lorsque les données ont été sauvegardées), mais étape. Si vous faites une erreur et faites la mauvaise procédure, vous corrompez les données ou, pire encore, vous présentez des problèmes de sécurité.
  • Vous pouvez traiter les différents formats de différentes sources problème en décidant que toutes les données transmises autour de votre application seront échappées. Ainsi, votre couche d'accès aux données va ré-échapper les données en l'obtenant de la base de données. Mais, comme les différentes parties de l'application ont besoin de s'échapper légèrement (ou complètement), cela conduit rapidement à beaucoup de non-sens. Récupérez les données de la base de données, échappez-la, évadez-la, évadez-la pour HTML, affichez-la.
  • Votre code de traitement de formulaire frontal doit avoir une connaissance approfondie de votre base de données. Par exemple, que signifie \' pour votre base de données? Comment un ' ou \ peut-il s'échapper - voire pas du tout? Si vous changez de moteur de base de données ou modifiez ses paramètres, ceux-ci peuvent changer. Et puis vous avez un tas de code d'échappement/de-fuite d'échappement à trouver. Manquer un seul échappement/échappement peut conduire à l'injection SQL. Vous pouvez également extraire cette connaissance de la base de données du code frontal en faisant en sorte que la couche de base de données effectue un cycle d'échappement/échappement pour convertir la séquence d'échappement de votre application en base de données. Mais cela semble plutôt idiot! Il y a une autre façon: laisser le calque dont les données ont besoin s'échapper lui-même. Les données sont toujours transmises entre les couches sous une forme brute, non échappée. Donc, votre couche d'accès aux données fait échapper toute la base de données. Votre code de sortie HTML évite tout échappement HTML. Lorsque vous décidez que vous voulez générer des fichiers PDF, votre code PDF évite tous les fichiers PDF. Maintenant, quand vous formez une sortie, il est clair que ce qu'il faut faire: toujours HTML échapper les données. Peu importe d'où il vient. Ne faites jamais de dégagement.
  • Il n'y a maintenant aucun non-échappement/évasion non-sens, car tout est passé autour brut. Il est seulement échappé quand nécessaire.
  • Votre code frontal ne se soucie pas de l'implémentation de la couche d'accès aux données. La couche d'accès aux données stocke et renvoie toute chaîne arbitraire.
  • Vous avez seulement un endroit à regarder dans votre application pour vous assurer que vous n'avez pas de problèmes d'injection SQL.
  • Vous pouvez facilement utiliser les fonctionnalités du pilote de base de données, telles que les espaces réservés. Alors même votre couche d'accès aux données ne doit pas être au courant des exigences d'échappement de chaque base de données; le pilote de base de données le gère.
7

Il est impossible d'ajouter une décision automatique d'échappement ou non si vous ne savez pas si l'entrée a été échappée. Vous pouvez essayer de l'analyser mais il ne sera jamais bon et vous rencontrerez des doubles paires de barre oblique inverse et autres.

Prenez la décision une fois que les données envoyées à votre couche d'accès doivent être propres et gérer l'échappement en un seul endroit. Si vous le faites, les autres développeurs n'auront pas à s'inquiéter à ce sujet (ils ne veulent probablement pas de toute façon) et il sera beaucoup plus facile de passer à une autre base de données à l'avenir. Il vous donnera également la liberté de passer à des états préparés à tout moment.

Edit: oublié ceci:

Ayant peu de contrôle sur l'entrée niveau (à moins que je passe en revue personnellement le code de tout le monde)

Je pense qu'il vaut la peine de les Découvrez-le vous-même si vous faites clairement comprendre que l'échappement est quelque chose qui appartient à la couche de base de données et ne devrait pas être fait ailleurs.

+3

+1 pour 'gérer l'échappement en un seul endroit'. J'aimerais pouvoir vous donner +5 pour ça ;-) – Treb

0

Si j'étais dans votre position, je ne serais pas assez paresseux pour ne pas revoir le code de tout le monde. Même si vous n'examinez pas l'échappement de l'entrée de l'utilisateur, vous pouvez toujours vérifier si le code est bien exécuté. Ou peut-être, ce n'est pas à vous de faire l'examen, mais quelqu'un doit le faire.

J'ai expérimenté une configuration presque similaire il n'y a pas si longtemps où nous avons divisé les tâches par couches. Un a travaillé sur le modèle, j'ai travaillé sur le contrôleur, et l'autre a travaillé sur les vues. Parce que nous faisions tellement confiance à tout le monde que le code de tout le monde fonctionne comme prévu, nous n'avons pas pris la peine d'examiner le code de l'autre jusqu'à ce que nous ayons besoin de les fusionner. Ce qui s'est passé, c'est que nous avons découvert du code inefficace dans le modèle tard dans le développement. Et ce n'était pas seulement inefficace, ça n'a pas marché! Pour cette raison, nous avons dû réviser d'énormes morceaux du code, ce qui nous a coûté plus de temps.

Je suggère que vous créez un document de spécifications techniques où il est spécifié dans les entrées acceptables des utilisateurs. Ce document devrait être suivi par ceux qui coderont la partie qui acceptera l'entrée de l'utilisateur. Mieux encore, créez des tests unitaires pour voir si ces exigences sont strictement suivies afin que vous n'ayez pas à vous inquiéter si les données qu'ils vont vous transmettre ne sont pas valides.

Autre chose ... puisque vous utilisez PHP, pourquoi ne pas utiliser un bon framework? La plupart des frameworks disponibles sont livrés avec leur propre DAL où vous n'avez plus besoin de vous soucier de l'échappement de la base de données (enfin, pas tant que ça). Les cadres devraient le faire pour vous.

De même, vous pouvez consulter les instructions préparées.

Questions connexes