Question

L'utilisateur n'est pas digne de confiance.Ne faites jamais confiance aux entrées d’utilisateurs non fiables.Je comprends ça.Cependant, je me demande quel est le meilleur moment pour nettoyer les entrées.Par exemple, stockez-vous aveuglément les entrées de l'utilisateur, puis les nettoyez-vous à chaque fois qu'elles sont consultées/utilisées, ou nettoyez-vous immédiatement les entrées, puis stockez-vous cette version « nettoyée » ?Il existe peut-être aussi d'autres approches auxquelles je n'ai pas pensé en plus de celles-ci.Je penche davantage pour la première méthode, car toutes les données provenant de la saisie de l'utilisateur doivent toujours être abordées avec prudence, car les données "nettoyées" peuvent toujours être dangereuses sans le savoir ou accidentellement.Quoi qu’il en soit, quelle méthode les gens pensent-ils être la meilleure et pour quelles raisons ?

Était-ce utile?

La solution

J'aime le nettoyer le plus tôt possible, ce qui signifie que le nettoyage se produit lorsque l'utilisateur tente de saisir des données invalides.S'il y a une zone de texte pour leur âge et qu'ils tapent autre chose qu'un nombre, je ne laisse pas passer la touche de la lettre.

Ensuite, peu importe ce qui lit les données (souvent un serveur), je fais un contrôle d'intégrité lorsque je lis les données, juste pour m'assurer que rien ne s'y glisse à cause d'un utilisateur plus déterminé (comme l'édition manuelle de fichiers, ou même la modification de paquets). !)

Modifier:Dans l’ensemble, effectuez une désinfection précoce et désinfectez chaque fois que vous perdez de vue les données, ne serait-ce qu’une seconde (par ex.Enregistrer le fichier -> Ouvrir le fichier)

Autres conseils

Malheureusement, presque aucun des participants ne comprend jamais clairement de quoi il parle.Littéralement.Seul @Kibbee a réussi à mettre les choses au clair.

Ce sujet concerne la désinfection.Mais la vérité est qu’une chose telle que la « désinfection à usage général » dont tout le monde est si impatient de parler est n'existe tout simplement pas.

Il y a un million de supports différents, chacun nécessite c'est son propre formatage de données distinct. De plus - même un seul support nécessite un formatage différent pour ses parties.Disons que le formatage HTML est inutile pour le javascript intégré dans la page HTML.Ou bien, le formatage des chaînes est inutile pour les nombres dans la requête SQL.

En fait, une telle « désinfection le plus tôt possible », comme le suggèrent la plupart des réponses votées positivement, n'est qu'une mesure. impossible.Comme on ne peut tout simplement pas dire dans quel média ou dans quelle partie les données seront utilisées.Disons que nous nous préparons à nous défendre contre "l'injection SQL", en échappant à tout ce qui bouge.Mais oups !- certains champs obligatoires n'ont pas été remplis et nous devons remplir les données dans le formulaire au lieu de la base de données...avec toutes les barres obliques ajoutées.

D'un autre côté, nous avons soigneusement échappé à toutes les "entrées de l'utilisateur"...mais dans la requête SQL, nous n'avons pas de guillemets autour, car il s'agit d'un numéro ou d'un identifiant.Et aucune « désinfection » ne nous a jamais aidés.

D'un troisième côté - d'accord, nous avons fait de notre mieux pour nettoyer les "entrées utilisateur" terribles, peu fiables et dédaignées...mais dans un processus interne, nous avons utilisé ces mêmes données sans aucun formatage (comme nous avons déjà fait de notre mieux !) - et oups !ont reçu une injection de deuxième ordre dans toute sa splendeur.

Donc, du point de vue de l'utilisation réelle, la seule manière appropriée serait

  • formatage, pas de "désinfection"
  • juste avant utilisation
  • selon certaines règles du milieu
  • et même en suivant les sous-règles requises pour les différentes parties de ce média.

Je nettoie mes données utilisateur un peu comme Radu...

  1. Premier côté client utilisant les deux regex et prendre le contrôle des caractères admissibles dans les champs de formulaire donnés à l'aide de JavaScript ou JQuery liés à des événements, tels qu'Onchange ou ONBLUR, qui supprime toute entrée refusée avant de pouvoir être soumise.Réalisez cependant que cela n'a vraiment que pour faire en sorte que ces utilisateurs soient au courant, que les données seront également vérifiées côté serveur.C'est plus un avertissement que toute protection réelle.

  2. Deuxièmement, et je vois rarement cela fait ces jours-ci, que la première vérification étant effectuée côté serveur consiste à vérifier l'emplacement de la présence du formulaire.En autorisant uniquement la soumission de formulaire à partir d'une page que vous avez désignée comme emplacement valide, vous pouvez tuer le script avant même d'avoir lu dans toutes les données.Certes, qui en soi est insuffisant, car un bon pirate avec leur propre serveur peut «parcourir» le domaine et l'adresse IP pour faire apparaître à votre script qu'il provient d'un emplacement de formulaire valide.

  3. Ensuite, et je ne devrais même pas avoir à dire ça, mais toujours, et je veux dire TOUJOURS, exécutez vos scripts en mode souillée.Cela vous oblige à ne pas devenir paresseux et à être diligent sur l'étape numéro 4.

  4. Désinfecter les données utilisateur dès que possible en utilisant des regex bien formés appropriés aux données attendues à partir d'un champ donné sur le formulaire.Ne prenez pas des raccourcis comme l'infâme 'corne magique de la licorne' pour faire exploser vos contrôles de contamination...Ou vous pouvez aussi bien désactiver la vérification de la souillure en premier lieu pour tout le bien qu'il fera pour votre sécurité.C'est comme donner à un psychopathe un couteau bien aiguisé, vous porter la gorge et dire "tu ne me feras vraiment pas de mal avec ça".

    Et c'est là que je différente de la plupart des autres dans cette quatrième étape, car je désoppacer les données de l'utilisateur que je vais réellement utiliser d'une manière qui pourrait présenter un risque de sécurité, comme tous les appels système, les affectations à d'autres variables, ou Toute écriture pour stocker des données.Si je n'utilise que les données d'entrée par un utilisateur pour faire une comparaison avec les données que j'ai moi-même stockées sur le système (sachant donc que mes données sont sûres), alors je ne prends pas la peine de désinfecter les données de l'utilisateur, car je Je ne nous vais jamais à nous un moyen qui se présente comme un problème de sécurité.Par exemple, prenez une entrée de nom d'utilisateur comme exemple.J'utilise l'entrée du nom d'utilisateur par l'utilisateur uniquement pour le vérifier par rapport à une correspondance dans ma base de données, et si elle est vraie, après cela, j'utilise les données de la base de données pour effectuer toutes les autres fonctions, je pourrais appeler pour cela dans le script, sachant qu'il est sûr , et n'utilisez plus jamais les données des utilisateurs après cela.

  5. Enfin, consiste à filtrer toutes les tentatives d'auto-subdireries par des robots ces jours-ci, avec un système «authentification humaine», comme le captcha.Ceci est assez important ces jours-ci pour que j'ai pris le temps d'écrire mon propre schéma «authentification humaine» qui utilise des photos et une entrée pour que «l'homme» d'entrer ce qu'ils voient sur l'image.Je l'ai fait parce que j'ai découvert que les systèmes de type captcha agacent vraiment les utilisateurs (vous pouvez dire par leurs yeux plissés d'essayer de déchiffrer les lettres déformées ...généralement encore et encore).Ceci est particulièrement important pour les scripts qui utilisent Sendmail ou SMTP pour les e-mails, car ce sont des favoris pour vos spam-bots affamés.

Pour résumer, je vais l'expliquer comme je le fais à ma femme...Votre serveur est comme une boîte de nuit populaire et plus vous avez de videurs, moins vous avez de problèmes dans la boîte de nuit.J'ai deux videurs devant la porte (validation côté client et authentification humaine), un videur juste à l'intérieur de la porte (vérification de l'emplacement valide de soumission du formulaire...«C'est vraiment vous sur cet identifiant»), et plusieurs autres videurs à proximité de la porte (exécuter le mode Taint et utiliser de bons regex pour vérifier les données de l'utilisateur).

Je sais que c'est un article plus ancien, mais je l'ai trouvé suffisamment important pour que quiconque puisse le lire après ma visite ici réalise que ce n'est pas le cas.balle magique' en matière de sécurité, et il faut que tous ces éléments travaillent en conjonction les uns avec les autres pour sécuriser les données fournies par vos utilisateurs.Utiliser une ou deux de ces méthodes seules ne sert pratiquement à rien, car leur pouvoir n’existe que lorsqu’elles font équipe.

Ou en résumé, comme disait souvent ma mère..."Mieux vaut prévenir que guérir".

MISE À JOUR:

Une autre chose que je fais ces jours-ci est le codage en Base64 de toutes mes données, puis le chiffrement des données Base64 qui résideront sur mes bases de données SQL.Il faut environ un tiers d'octets supplémentaires pour le stocker de cette façon, mais les avantages en matière de sécurité dépassent à mon avis la taille supplémentaire des données.

Cela dépend du type de désinfection que vous effectuez.

Pour vous protéger contre l'injection SQL, ne faites rien sur les données elles-mêmes.Utilisez simplement des instructions préparées, et de cette façon, vous n'avez pas à vous soucier de modifier les données saisies par l'utilisateur et de les voir affecter négativement votre logique.Vous devez nettoyer un peu pour vous assurer que les nombres sont des nombres et que les dates sont des dates, puisque tout est une chaîne car elle provient de la demande, mais n'essayez pas de faire des vérifications pour faire des choses comme bloquer des mots-clés ou quoi que ce soit.

Pour se protéger contre les attaques XSS, il serait probablement plus facile de réparer les données avant qu'elles ne soient stockées.Cependant, comme d'autres l'ont mentionné, il est parfois agréable d'avoir une copie intacte de ce que l'utilisateur a saisi, car une fois que vous la modifiez, elle est perdue à jamais.C'est presque dommage qu'il n'existe pas de moyen infaillible de garantir que votre application ne publie que du HTML purifié de la même manière que vous pouvez vous assurer de ne pas vous faire prendre par l'injection SQL en utilisant des requêtes préparées.

Le plus important est de toujours être cohérent lorsque vous vous échappez.Une double désinfection accidentelle est boiteuse et ne pas désinfecter est dangereux.

Pour SQL, assurez-vous simplement que votre bibliothèque d'accès à la base de données prend en charge les variables de liaison qui échappent automatiquement aux valeurs.Quiconque concatène manuellement les entrées utilisateur sur des chaînes SQL devrait le savoir mieux.

Pour le HTML, je préfère m'évader au dernier moment possible.Si vous détruisez les entrées des utilisateurs, vous ne pourrez jamais les récupérer, et s'ils font une erreur, ils pourront les modifier et les corriger plus tard.Si vous détruisez leur contribution originale, elle disparaîtra pour toujours.

Tôt, c'est bien, certainement avant d'essayer de l'analyser.Tout ce que vous allez afficher plus tard, ou surtout transmettre à d'autres composants (c'est-à-dire Shell, SQL, etc.) doit être nettoyé.

Mais n'allez pas trop loin : par exemple, les mots de passe sont hachés avant que vous ne les stockiez (n'est-ce pas ?).Les fonctions de hachage peuvent accepter des données binaires arbitraires.Et vous n’imprimerez jamais de mot de passe (n’est-ce pas ?).Alors n’analysez pas les mots de passe et ne les désinfectez pas.

Assurez-vous également que vous effectuez la désinfection à partir d'un processus fiable - JavaScript/tout ce qui est côté client est pire qu'une sécurité/intégrité inutile.(Cela pourrait cependant offrir une meilleure expérience utilisateur en cas d'échec précoce - faites-le simplement aux deux endroits.)

Perl a une option de contamination qui considère toutes les entrées utilisateur comme « entachées » jusqu'à ce qu'elles soient vérifiées avec une expression régulière.Les données corrompues peuvent être utilisées et transmises, mais elles altèrent toutes les données avec lesquelles elles entrent en contact jusqu'à ce qu'elles soient intactes.Par exemple, si une entrée utilisateur est ajoutée à une autre chaîne, la nouvelle chaîne est également entachée.Fondamentalement, toute expression contenant des valeurs entachées produira un résultat entaché.

Les données corrompues peuvent être diffusées à volonté (altérant les données au fur et à mesure), mais dès qu'elles sont utilisées par une commande ayant un effet sur le monde extérieur, le script Perl échoue.Donc, si j'utilise des données corrompues pour créer un fichier, construire une commande shell, modifier le répertoire de travail, etc., Perl échouera avec une erreur de sécurité.

Je ne connais pas d'autre langage qui ait quelque chose comme "tache", mais son utilisation a été très révélatrice.Il est étonnant de constater à quelle vitesse les données corrompues se propagent si vous ne les corrigez pas immédiatement.Des choses naturelles et normales pour un programmeur, comme définir une variable basée sur les données utilisateur ou ouvrir un fichier, semblent dangereuses et risquées lorsque la corruption est activée.La meilleure stratégie pour faire avancer les choses est donc de les nettoyer dès que vous obtenez des données de l’extérieur.

Et je soupçonne que c'est également la meilleure façon de procéder dans d'autres langues :validez immédiatement les données utilisateur afin que les bugs et les failles de sécurité ne puissent pas se propager trop loin.En outre, il devrait être plus facile de vérifier le code pour détecter les failles de sécurité si les failles potentielles se trouvent au même endroit.Et vous ne pouvez jamais prédire quelles données seront utilisées dans quel but plus tard.

Mon avis est de nettoyer les entrées des utilisateurs dès que possible côté client et côté serveur, je le fais comme ça

  1. (côté client), permettez à l'utilisateur de saisir des touches spécifiques dans le champ.
  2. (côté client), lorsque l'utilisateur va au champ suivant à l'aide d'Onblur, testez l'entrée qu'il a entrée contre un regexp et remarquez l'utilisateur si quelque chose n'est pas bon.
  3. (côté serveur), testez à nouveau l'entrée, si le champ doit être entier vérifiez (en php, vous pouvez utiliser is_numeric ()), si le champ a un format bien connu, vérifiez-le par rapport à un regexp, tous les autres (comme les commentaires de texte), Échappez-leur simplement.Si quelque chose est suspect, arrêtez l'exécution du script et renvoyez une notification à l'utilisateur indiquant que les données qu'il a saisies ne sont pas valides.

Si quelque chose ressemble vraiment à une attaque possible, le script m'envoie un mail et un SMS, afin que je puisse le vérifier et peut-être l'empêcher dès que possible, j'ai juste besoin de vérifier le journal dans lequel j'enregistre toutes les entrées utilisateur, et les étapes effectuées par le script avant d'accepter l'entrée ou de la rejeter.

Nettoyez les données avant de les stocker.En général, vous ne devriez pas vous préformer N'IMPORTE LEQUEL Actions SQL sans nettoyage préalable des entrées.Vous ne voulez pas vous soumettre à une attaque par injection SQL.

Je suis en quelque sorte ces règles de base.

  1. Effectuez uniquement la modification des actions SQL, telles que INSERT, UPDATE, DELETE via POST.Ne jamais obtenir.
  2. Échapper à tout.
  3. Si vous vous attendez à ce que l'entrée de l'utilisateur soit quelque chose, assurez-vous de vérifier qu'il s'agit bien de quelque chose.Par exemple, vous demandez un numéro, alors assurez-vous qu'il s'agit bien d'un numéro.Utilisez les validations.
  4. Utilisez des filtres.Nettoyez les caractères indésirables.

Les utilisateurs sont méchants !

Eh bien, peut-être pas toujours, mais mon approche est de toujours désinfecter immédiatement pour m'assurer que rien de risqué ne se trouve à proximité de mon backend.

L'avantage supplémentaire est que vous pouvez fournir un retour d'information à l'utilisateur si vous effectuez une désinfection au point d'entrée.

Supposons que tous les utilisateurs soient malveillants.Désinfectez toutes les entrées dès que possible.Arrêt complet.

Je nettoie mes données juste avant d'y effectuer un traitement.Je devrai peut-être prendre les champs Prénom et Nom et les concaténer dans un troisième champ qui sera inséré dans la base de données.Je vais nettoyer l'entrée avant même de faire la concaténation afin de ne pas recevoir d'erreurs de traitement ou d'insertion.Le plus tôt sera le mieux.Même l'utilisation de Javascript sur le front-end (dans une configuration Web) est idéale car cela se produira sans qu'aucune donnée ne soit transmise au serveur pour commencer.

Ce qui est effrayant, c’est que vous voudrez peut-être même commencer à nettoyer les données provenant de votre base de données.La récente vague d'attaques ASPRox SQL Injection qui circulent est doublement mortelle car elle infectera toutes les tables de base de données d'une base de données donnée.Si votre base de données est hébergée dans un endroit où plusieurs comptes sont hébergés dans la même base de données, vos données sont corrompues à cause de l'erreur de quelqu'un d'autre, mais vous avez maintenant rejoint les rangs des hébergeurs de logiciels malveillants destinés à vos visiteurs sans faute initiale de votre part. .

Bien sûr, cela demande beaucoup de travail au départ, mais si les données sont critiques, alors c'est un investissement qui en vaut la peine.

Je trouve que le nettoyer présente immédiatement deux avantages.Premièrement, vous pouvez le valider et fournir des commentaires à l'utilisateur.Deuxièmement, vous n’avez pas à vous soucier de consommer les données ailleurs.

Les entrées utilisateur doivent toujours être traitées comme malveillantes avant de les intégrer aux couches inférieures de votre application.Gérez toujours les entrées de désinfection dès que possible et ne doivent pour aucune raison être stockées dans votre base de données avant de vérifier toute intention malveillante.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top