Question:
Le filtrage par guillemets simples est-il absurde?
Peter Walser
2019-02-04 19:28:37 UTC
view on stackexchange narkive permalink

Les testeurs de pénétration ont découvert que nous autorisons les guillemets simples dans les champs de données soumis et veulent que nous appliquions des règles (validation d'entrée) pour ne les autoriser dans aucune valeur.

Bien que je sache que les guillemets simples sont populaires pour les attaques par injection SQL, je ne suis pas du tout d'accord sur le fait qu'elles ne devraient pas être autorisées comme entrées valides. Je préconise d'empêcher l'injection SQL en utilisant des instructions préparées (qui citent correctement les valeurs) au lieu de filtrer tout ce qui ressemble à distance à un fragment SQL.

Mon cas:

  • Les noms de personne peuvent contenir des guillemets simples (tels que O'Reilly)
  • Les champs de texte peuvent contenir des guillemets simples (tels que Je suis presque sûr )
  • Les champs numériques peuvent contenir des guillemets simples ( EUR 1'000'000 )
  • et bien d'autres

J'ai vu d'autres cas où l'application de règles de prévention d'injection SQL a attribué des données valides pour les raisons les plus stupides (nom " Andreas " rejeté car il contient un ET , et divers les mots courants dans les champs de texte brut ont été rejetés car ils contenaient les mots clés " select ", " insert ", " update " ou " delete ").

Quelle est la position des professionnels de la sécurité à ce sujet?

Rejetons la mise en œuvre de la validation d'entrée pour les guillemets simples pour les raisons que j'ai indiquées?

Les commentaires ne sont pas destinés à une discussion approfondie;cette conversation a été [déplacée vers le chat] (https://chat.stackexchange.com/rooms/89472/discussion-on-question-by-peter-walser-is-single-quote-filtering-nonsense).
Je serais inquiet si vos testeurs pent pensent qu'empêcher l'utilisateur de soumettre une apostrophe empêchera en quelque sorte les attaques par injection SQL ...
Je suis d'accord avec votre logique.Je les ferais essayer d'exécuter une attaque par injection SQL sur un environnement UAT / QA.Ils doivent également comprendre que l'entrée de l'utilisateur n'est pas dangereuse, c'est la façon dont elle est traitée qui la rend potentiellement dangereuse.
Douze réponses:
Sjoerd
2019-02-04 19:38:54 UTC
view on stackexchange narkive permalink

Vous devez implémenter la validation d'entrée en tant que méthode de défense en profondeur. Ainsi, la validation d'entrée ne doit pas être votre principale défense contre l'injection SQL, mais plutôt des instructions préparées. Comme défense supplémentaire, vous devez restreindre les entrées autorisées.

Cela ne devrait jamais restreindre les fonctionnalités. S'il existe un cas d'utilisation légitime pour avoir des apostrophes en entrée, vous devez l'autoriser. Vous devriez donc autoriser les guillemets simples dans les champs de nom, les descriptions, les mots de passe, mais pas dans les champs numériques, les champs de nom d'utilisateur, les champs de plaque d'immatriculation.

Bloquer les guillemets simples dans toutes les entrées est de la folie. Cela casse la fonctionnalité de l'application et n'est même pas la bonne solution contre l'injection SQL.

Considérez la possibilité que vous ayez mal compris l'entreprise de pentesting. Si c'est sérieusement leur conseil, cela reflète mal la société de pentesting et je vous conseillerais de rechercher un partenaire de pentesting qui aide à sécuriser correctement votre logiciel, au lieu de le rendre inutilisable.

Les commentaires ne sont pas destinés à une discussion approfondie;cette conversation a été [déplacée vers le chat] (https://chat.stackexchange.com/rooms/89356/discussion-on-answer-by-sjoerd-is-single-quote-filtering-nonsense).
+1 Mais, les plaques d'immatriculation [au Missouri peuvent avoir des apostrophes.] (Https://dor.mo.gov/motorv/plates/specialty.php#personalized) Les numéros ne doivent pas être stockés sous forme de texte * ou * s'ils sont (par exemple, une partie d'un champ "commentaires"), OP a montré une chaîne numérique dans une culture avec des apostrophes.[Soyez prudent lorsque vous assumez.] (Https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/)
Christoph Burschka
2019-02-05 15:38:36 UTC
view on stackexchange narkive permalink

C'est clairement faux dans le contexte des attaques par injection - soit votre couche de base de données traite correctement les chaînes, soit elle ne le fait pas. Puisque les apostrophes sont valides dans les noms et le texte libre, les bloquer complètement cassera l'application, et les bloquer de manière sélective ne résoudrait pas les problèmes d'injection.

Mais une validation d'entrée stricte est bonne pratiquer sur des principes généraux, et être trop permissif n'a pas de sens dans les cas où l'apostrophe ne fait pas partie d'une valeur légitime. Vous donnez l'exemple de EUR 1'000'000 , qui est un format spécifique à la locale (Suisse uniquement, AFAIK) - mais autoriser le format à faire partie de la valeur n'a aucun sens ici. Si l'utilisateur saisit 1 500 , votre application doit-elle stocker cela tel quel? Aurez-vous à décider à chaque fois qu'il est traité s'il doit être interprété comme 1,5 ou comme 1500? Il serait plus judicieux de gérer la présentation spécifique aux paramètres régionaux côté client et de traiter la valeur numérique sous une forme canonique en interne.

La réponse ici dépendrait donc de la question de savoir si l'audit se plaint de champs spécifiques là où cela a du sens, ou recommander une interdiction générale des apostrophes. Si le premier, c'est un point légitime. Dans ce dernier cas, ils sont stupides et suivent probablement aveuglément une liste de contrôle.

Notez que dans le cas du format spécifique à la locale, la meilleure réponse n'est peut-être pas de l'interdire mais de l'analyser d'une manière ou d'une autre et de générer le nombre sans lui.
@jpmc26 Les nombres sont faciles: une chaîne d'entrée numérique fournie par l'utilisateur peut contenir un nombre entier ou un nombre décimal.Pour le premier, déposez simplement tous les non-chiffres et continuez.Pour les décimales, je recherche généralement le premier caractère de point ou de virgule * de droite à gauche * laissez tomber le reste, puis remplacez-le par le séparateur décimal nécessaire et continuez.
@beppe9000 Il serait encore plus simple d'utiliser une bibliothèque d'analyse.Il peut cependant avoir besoin d'être frontal pour détecter les paramètres régionaux de l'utilisateur.
@jpmc26 Ouais, la localisation appartient au front-end.La prise de données ne se soucie que de la normalisation: lors de la diffusion de pages, on peut utiliser les bibliothèques js pour formater les chaînes en fonction des préférences de l'utilisateur (qu'elles soient stockées dans la base de données ou sous forme de cookie).
@beppe9000 Alors, comment interprétez-vous "1 500" sans informations locales?Quinze cents, ou un et demi?
@Guran mon point est que vous effectuez une validation de formulaire sur le client, puis utilisez une culture neutre sur le serveur.Lorsque vous avez besoin d'afficher une valeur dans la culture de l'utilisateur, vous la formatez en js.Stocker des nombres sous forme de chaînes est tout simplement faux, à mon humble avis.
@beppe9000 True.Pourtant, chaque fois que vous recevez des nombres au format chaîne, vous êtes SOL sauf si vous connaissez la culture.
@Guran Si cela se produit, cela signifie que quelqu'un contourne la validation du formulaire.Alors essayez de normaliser côté serveur vers une culture neutre (selon le type et la plage de nombres attendus) ou punissez-les avec une erreur 400.À moins que vous ne vouliez réellement que la douleur des nombres soit des chaînes, auquel cas vous utilisez des bibliothèques, des en-têtes de requête, GeoIP et DNS inversé pour se rapprocher d'une locale, et si tout échoue, envoyez une erreur ou une analyse comme neutre.
Joshua
2019-02-05 04:51:22 UTC
view on stackexchange narkive permalink

Étape 1) Paramétrez votre SQL.

Étape 2) Assurez-vous que vous utilisez la bibliothèque SQL DB Connection pour définir les valeurs de vos paramètres, pas simplement en les définissant en ligne. C'est la véritable défense contre l'injection SQL.

Étape 3) Ne faites pas de création de requêtes en SQL. C'est de la folie.

Étape 4) ajoutez un commutateur de configuration pour propager l'erreur jusqu'à l'utilisateur. Activez-le pendant le test.

Étape 5) Dites à vos testeurs d'intrusion de trouver un moyen de générer une erreur SQL avec un nombre impair de guillemets simples ou fermez-vous.

+1 pour l'étape 3).Vérité absolue.
DarkMatter
2019-02-04 19:41:52 UTC
view on stackexchange narkive permalink

Les instructions préparées (requêtes paramétrées) sont excellentes, assurez-vous simplement de les implémenter correctement. J'ai vu des implémentations de "déclaration préparée" qui étaient tout aussi vulnérables. Pour discuter des détails d'implémentation, je recommande le débordement de pile.

Aussi rien de mal avec la défense en profondeur (validation d'entrée dans ce cas) mais faites-le bien ... rejeter tous les guillemets simples n'est probablement pas la meilleure pratique :)

Les commentaires ne sont pas destinés à une discussion approfondie;cette conversation a été [déplacée vers le chat] (https://chat.stackexchange.com/rooms/89473/discussion-on-answer-by-darkmatter-is-single-quote-filtering-nonsense).
Schwern
2019-02-09 05:44:27 UTC
view on stackexchange narkive permalink

Je ne suis pas un agent de sécurité. Je suis un programmeur qui doit maintenir un code sécurisé. C'est ce que j'appelle une pratique «fragile». Les points d'entrée sont dispersés dans un projet typique. Les trouver et les désinfecter tous est beaucoup de travail pour résoudre un seul problème, beaucoup de maintenance minutieuse et de tracas pour s'assurer qu'il reste efficace lorsque le code change, et plein d'hypothèses qui le rendent inefficace.

Utilisez plutôt des pratiques plus faciles à entretenir, en couches, contextuelles et qui résolvent un large éventail de problèmes. Vous n'avez alors pas besoin d'un filtrage coûteux et trop large.

Vous ne pouvez pas sécuriser les entrées si vous ne savez pas comment elles seront utilisées.

Disons que vous avez "sécurisé" votre système en supprimant tous les guillemets simples de toutes les entrées à travers le tableau. Super, vous êtes à l'abri d'un un type d'attaque par injection SQL. Que faire si cette entrée est utilisée dans une ...

  • requête MySQL qui autorise les guillemets doubles
  • Opération du système de fichiers
  • Commande Shell
  • Requête réseau
  • Nom de la méthode
  • Nom de la classe
  • eval

Chacun des ceux-ci ont des caractères spéciaux, des séquences d'échappement, des règles de citation et des pratiques de sécurité différents. Vous ne pouvez pas prédire comment votre entrée sera utilisée lorsqu'elle entrera. Essayer de supprimer tous les caractères spéciaux est de la folie et ne "résout" qu'une seule classe d'attaque.

Ou que faire si l'utilisateur est autorisé pour saisir une limite de pages. Cette limite est consciencieusement utilisée dans une requête paramétrée; pas d'injection SQL, yay! L'utilisateur entre 9999999999 et vous êtes maintenant ouvert à une attaque DOS.

Vous devez appliquer les mesures de sécurité appropriées au moment où l'opération potentiellement non sécurisée est effectuée. Cela prend en compte de nombreux facteurs propres à l'opération; nettoyer les caractères d'entrée n'en est qu'un.

Et tant que vous faites cela, vous pouvez aussi paramétrer vos requêtes. Ensuite, il n'est plus nécessaire de faire tout le travail et les dégâts des citations de décapage de couverture.

Filtrer toutes les entrées est difficile.

Il existe de très nombreuses façons d'obtenir et de transmettre des entrées dans un projet donné:

  • entrées de formulaire
  • urls
  • noms de fichier
  • contenu de fichier
  • requêtes de base de données
  • lecture réseau
  • variables d'environnement

Ils sont généralement assez libres et peuvent utiliser de nombreuses bibliothèques différentes. Je ne connais aucun outil d'analyse statique qui vérifie que toutes les entrées potentiellement vulnérables ont été filtrées. Certaines langues ont un système taint , mais elles sont difficiles à utiliser efficacement. Même si vous filtrez toutes les entrées, sans outil d'analyse statique, les entrées non filtrées reviendront au fur et à mesure du développement. Cela demande beaucoup d'efforts pour un résultat incomplet et coûteux à maintenir, ce qui nuit à la fonctionnalité.

En revanche, il n'y a généralement qu'une seule façon d'exécuter SQL dans un projet. Des outils statiques et d'exécution existent pour détecter automatiquement une injection SQL potentielle. Vous pouvez même interdire complètement les chaînes et exiger que toutes les requêtes soient des objets de requête SQL. Ces bonnes pratiques sont faciles à maintenir et de plus en plus intégrées dans les outils et les bibliothèques SQL.

Les "pare-feu" conduisent à une sécurité laxiste.

Semblable à la façon dont certains réseaux de bureau ont des pratiques très peu sécurisées car " nous avons un pare-feu ", l'équipe risque de devenir paresseuse pour sécuriser son code car" l'entrée est sûre ". L'entrée n'est certainement pas sûre.

Coût d'opportunité

Certains pourraient dire "pourquoi pas les deux?" Vous n'avez que quelques heures pour travailler sur un projet. Une pratique à faible efficacité et à entretien élevé est une perte de temps. Sa mise en œuvre et sa maintenance vous feront perdre un temps limité de pratiques plus efficaces et plus faciles à entretenir. Dans le pire des cas, vous passerez tellement de temps à jouer à whack-a-mole avec des entrées, et les problèmes ultérieurs causés par un filtrage trop agressif, que vous n'aurez jamais le temps de prendre des mesures de sécurité appropriées.

En bref, le filtrage des entrées est coûteux, fuit, difficile à maintenir, ne peut pas résoudre le problème et pourrait l'aggraver.

Philip Rowlands
2019-02-04 19:38:58 UTC
view on stackexchange narkive permalink

Comme vous l'avez dit vous-même, si vous utilisez des requêtes paramétrées, les guillemets simples ne posent pas de problème. Dans ce cas, vous pouvez rejeter leur avis. Dans ce cas, mettez en évidence le fait que vous utilisez des requêtes paramétrées et que cela facilite également l’utilisation (en utilisant vos exemples précédents).

Erik A
2019-02-04 21:20:11 UTC
view on stackexchange narkive permalink

Si vous êtes sûr à 100% de toujours empêcher l'injection SQL partout, c'est en effet un non-sens.

Cependant, l'injection SQL est l'un des risques de sécurité les plus courants, et même si vous êtes sûr que vous Si vous avez correctement écrit votre application pour utiliser des paramètres, un DBA bâclé peut exécuter une requête qui risque de subir une injection SQL de second ordre. Il peut même ne pas être stocké n'importe où, il peut simplement s'agir d'une requête pour copier une table.

Les attaques de second ordre sont plus difficiles à exécuter, mais plus difficiles à protéger. La protection contre les attaques de second ordre signifie que chaque instruction SQL dynamique exécutée sur la base de données avec des autorisations d'écriture doit être vérifiée pour un risque d'injection SQL, pas seulement les instructions SQL qui traitent les entrées provenant de sources non fiables.

Interdiction des guillemets partout est une protection bâclée contre les attaques de second ordre, mais les rend moins probables. Dans un monde idéal, ce ne serait pas nécessaire, mais malheureusement, nous ne vivons pas dans un seul.

Si de nombreux utilisateurs ont une forme quelconque d'accès en écriture sur la base de données et sont capables d'écrire leurs propres instructions SQL, cela peut être une mesure de sécurité judicieuse. Si votre application est le seul moyen d'accéder à la base de données et que seuls des utilisateurs très bien informés peuvent exécuter leurs propres requêtes avec un accès en écriture, ce n'est généralement pas nécessaire.

Certes, je ne connais pas bien le pentesting ou le PL / SQL (dont je suppose qu'il s'agit) en général, mais l'injection SQL de second ordre semble vraiment horrible.Si nous avons collectivement appris que l'utilisation de `eval ()` sur l'entrée utilisateur n'est pas une bonne idée, pourquoi alors utilisons-nous ce genre de construction en PL / SQL?J'espère qu'il existe une autre façon de faire cette requête derrière votre lien qui respecte la différence entre le code et les données.
@tomsmeding L'injection de second ordre est possible dans la plupart des dialectes SQL (T-SQL via `sp_executesql`, PL / SQL via` EXECUTE IMMEDIATE`, MySQL via `EXECUTE`).Ils prennent tous en charge les paramètres, vous pouvez donc le faire correctement, mais il existe des limitations.Par exemple, j'ai migré les requêtes pivot Access SQL vers T-SQL, et la seule façon de le faire dans T-SQL est d'utiliser la concaténation de chaînes pour obtenir des noms de champs dynamiques comme le fait Access (avec des caractères d'échappement, mais les caractères d'échappement sont mauvais, et j'ai rencontré des exemples de scripts sans eux), car vous ne pouvez pas utiliser de paramètres pour les noms de champs.
@tomsmeding: À moins que les choses n'aient changé, il n'y a pas de moyen agréable d'exécuter quelque chose de la forme "select * where id is in [list]" sans utiliser de SQL généré dynamiquement pour spécifier la liste.Je n'essaierais pas une telle chose avec les éléments spécifiés par l'utilisateur dans la liste, mais avec les ID numériques traités à l'aide de types de données numériques, je ne vois aucun risque d'injection.
@supercat, cela peut certainement être fait - par exemple, pour python / postgres, cela se fait comme http://initd.org/psycopg/docs/usage.html#lists-adaptation ou http://initd.org/psycopg/docs/usage.html # tuples-adaptation, il existe donc un support de pilote et des fonctionnalités similaires devraient être disponibles pour d'autres langages / moteurs de base de données.
@Peteris: La bibliothèque Psycopg passe-t-elle des tableaux au moteur SQL en tant que paramètres, ou les étend-elle sous la forme d'une commande qui prend un nombre variable de paramètres individuels, ou quoi?
@supercat Je ne peux pas être certain sans regarder plus dans les internes psycopg2 que ne le disent les documents de l'API, mais comme les tableaux sont un type de données postgresql natif (https://www.postgresql.org/docs/9.0/arrays.html), c'est possible (et donc nécessaire de prendre en charge) en tant que valeur pour les colonnes dans tout SELECT aléatoire, alors je suppose que le pilote doit prendre en charge l'échange de tableaux sous une forme appropriée, pas un hack stringifié.
PostgreSQL fournit une bien meilleure défense contre l'injection dans les requêtes `EXECUTE IMMEDIATE`: un ensemble de fonctions qui citeront correctement l'entrée.Ce sont [`quote_ident`] (https://www.postgresql.org/docs/current/functions-string.html#id-1.5.8.9.7.2.2.21.1.1), [` quote_literal`] (https: //www.postgresql.org/docs/current/functions-string.html#id-1.5.8.9.7.2.2.22.1.1) et [`quote_nullable`] (https://www.postgresql.org/docs/current/functions-string.html#id-1.5.8.9.7.2.2.24.1.1).Évidemment, il est préférable d'éviter «EXECUTER IMMEDIATE», mais ce sont des mondes meilleurs pour la désinfection si vous devez l'utiliser.
@supercat Je ne connais pas spécifiquement psycopg2, mais je sais que certaines bibliothèques clientes étendent le tableau en paramètres individuels pour certaines bases de données, comme `IN (: p1,: p2,: p3 ...)`.Voilà donc au moins une technique.
@supercat Ne feriez-vous pas quelque chose comme `sélectionnez le nom d'utilisateur de usertab rejoignez sessiontab sur usertab.id = sessiontab.id où sessions.token = `?Peut-être que les performances, je suppose, mais une jointure complète comme celle-ci est de toute façon optimisée par le planificateur de requêtes et même si ce n'est pas le cas pour une raison quelconque, vous pouvez toujours la forcer en vous joignant à une sous-requête à la place.
@IMSoP C'est en référence à l'exemple lié dans la réponse.J'utilise simplement «» pour désigner la syntaxe d'instruction préparée dont votre pilote SQL a besoin pour l'opération réelle.Quant à une clause `IN` fournie par l'utilisateur, ce n'est pas vraiment ce à quoi je veux en venir;plutôt dans l'exemple lié, l'injection SQL de second ordre, il semble que ce soit principalement une conséquence de l'utilisation d'une sorte d'expansion de chaîne janky au milieu de la requête.Je ne suis pas un expert DBA, mais cela ne montre pas exactement pourquoi vous pourriez avoir besoin d'exécuter une requête qui serait vulnérable à ce problème en premier lieu.
J'ai fait ça une fois.Chaque chaîne utilisateur était immédiatement codée en HTML.Je pense maintenant que c'est un mauvais choix architectural.
@AJMansfield OK, j'étais confus parce que votre commentaire était adressé à `supercat`, donc je pensais qu'il était lié à leur exemple" select * where id is in [list] ", plutôt qu'à la réponse (qui a été écrite par quelqu'un d'autre).
-1
Tobi Nary
2019-02-04 19:38:39 UTC
view on stackexchange narkive permalink

Bien que je ne connaisse pas les spécificités de votre application, je suis votre argument.

Il y a des champs qui n'ont pas besoin de contenir certains caractères. Avec ces champs, vous pourriez utiliser la validation d'entrée pour filtrer les guillemets simples (et les guillemets doubles, etc.).

Si votre échappement ne fonctionnait pas correctement, la validation d'entrée pourrait être une stratégie d'atténuation, mais l'utilisation d'instructions préparées (correctement) devrait être l'approche préférable pour atténuer les risques d'injection SQL.

Jason Leaman
2019-02-05 16:14:23 UTC
view on stackexchange narkive permalink

S'il s'agit du résultat d'un véritable test de pénétration, ils devraient être en mesure de vous fournir une valeur à soumettre qui prouve qu'il s'agit d'un problème exploitable. S'ils ne peuvent pas alors je suggérerais de demander un test de pénétration approprié, où ils prouvent que cela est exploitable.

Si toutefois c'est le résultat d'un scan de vulnérabilité générique alors je m'attendrais à des réponses génériques floues comme celle-ci, qui signalerait simplement la possibilité d'insérer un guillemet simple. Dans ce cas, si vous êtes satisfait qu'il n'y ait pas de problème, vous pouvez ignorer ce résultat avec plaisir.

Cette réponse ne répond pas réellement à la question.La question ne concerne pas la méthodologie de test, mais comment filtrer.Veuillez vous assurer que vos réponses répondent directement à la question.Nous aimons les différentes perspectives et informations, mais cela semble être une tangente.
@schroeder: Il dit de deux manières "afin que vous puissiez taper un guillemet simple, maintenant où est la vulnérabilité?"et le second conteste le cadre selon lequel le filtrage des guillemets simples est bon pour la sécurité.
@schroeder La question est "Que dois-je faire à propos de ce rapport d'un test de pénétration?"Cette réponse dit "Vérifiez s'il s'agit d'une véritable vulnérabilité, et si non, ignorez-la comme un faux positif."Je ne sais pas pourquoi ce serait une tangente.
@IMSoP ce n'est pas du tout la question, c'est une méta-abstraction de la question.Si telle est en fait la question, alors le PO s'auto-répond (le PO décrit précisément cette réponse).
@Joshua l'OP conteste spécifiquement le cadre de manière très détaillée, donc encore une fois, je ne suis pas sûr de ce que cette réponse que nous risquons de fournir.
@schroeder Je ne suis pas sûr de ce que vous entendez par «méta abstraction».Le texte littéral de la question se termine "Devons-nous rejeter la mise en œuvre de la validation d'entrée pour les guillemets simples pour les raisons que j'ai indiquées?"Le texte littéral de cette réponse se termine "Dans ce cas ... vous pouvez volontiers ignorer ce résultat".Ce n'est pas la réponse la plus détaillée, mais c'est une réponse.
@scheoeder: C'est à peu près une dupe des autres réponses, mais NAA ne devrait être utilisé que si même si c'était la seule réponse, il est mauvais.
Mais dans ce cas, une grande quantité de réponses disant que les pentesters sont faux est souhaitable.
@IMSoP les 2 déclarations que vous avez citées ne sont en aucun cas liées les unes aux autres
@schroeder Je ne sais pas à quel point ils pourraient être liés.«Devrions-nous X?"Si O, alors oui".
MrNiceGuy
2019-02-04 21:27:11 UTC
view on stackexchange narkive permalink

D'un ancien développeur Web et maintenant moi-même un testeur de stylet, je ne voudrais pas restreindre l'entrée des utilisateurs, mais cela peut être un problème majeur. Je sais que j'ai moi-même utilisé cette technique pour compromettre les applications Web et les bases de données.

Mon avis serait de vérifier votre installation DB et la configuration du langage Web (php) pour gérer les caractères d'échappement, puis coder un ou plusieurs modules pour itérer l'entrée pour s'assurer qu'elle est correctement formatée.

Une apostrophe peut être une entrée valide mais peut aussi échapper à votre instruction de base de données en cours de transmission et introduire un vecteur d'attaque. Les bases de données et les langages Web ont des modules qui peuvent gérer ces types d'instances, mais c'est toujours une bonne idée d'écrire votre propre module pour vérifier.

OP a tout paramétré correctement, donc les caractères d'échappement ne doivent être utilisés nulle part.En outre, [ils ne fournissent pas toujours la sécurité] (https://stackoverflow.com/a/12118602/7296893), même lorsqu'ils sont mis en œuvre correctement.
Bien entendu, en fonction de la pile et des frameworks que vous utilisez, des contrôles de cohérence supplémentaires peuvent être utiles.Dans mon cas, j'utilise Java / JDBC avec des instructions préparées, sur Spring Data JPA, avec des requêtes JPQL paramétrées - ce truc est à peu près solide.
ANone
2019-02-12 20:05:06 UTC
view on stackexchange narkive permalink

Je pense que c'est une question de perspective. Votre système a une exigence fonctionnelle qui doit venir en premier. Cela ne veut pas dire que cela ne vaut pas la peine de considérer la question de la validation des entrées. BTW, les deux ne sont pas directement en désaccord. Je ne le recommande pas, mais il serait possible d'encoder et de décoder dans le front-end et de faire en sorte que le stockage SQL et la requête utilisent la forme encodée.

L'équilibre est subjectif et dépend d'une multitude de choses pas mentionné. Vous pourriez essayer de leur demander de clarifier. Ils peuvent avoir une très bonne raison, mais peut-être pas.

Dewi Morgan
2019-02-05 09:22:48 UTC
view on stackexchange narkive permalink

Je vais contredire la plupart des autres réponses actuelles.

Vos pentesters sont presque certainement corrects à 100%.

Mon hypothèse: aucun pentester vaut leur sel l'aurait signalé à moins qu'il n'ait constaté que votre application acceptait et faisait écho aux apostrophes dans une situation où aucune apostrophes n'était valide.

Peut-être que vos noms d'utilisateur, numéros de téléphone, noms de domaine et dates devraient tous avoir des formats spécifiques et plages de caractères. Tous devraient manquer d'apostrophes. Mais à la place, vous n'acceptez que n'importe quelle ancienne chaîne qu'ils vous donnent, pour tous ces champs.

Si cette hypothèse est fausse et que vous validez déjà vos entrées aussi strictement que possible, alors ils ont tort, et vous allez bien.

Si cette hypothèse est vraie et que les apostrophes seraient invalides dans cette entrée, alors:

  • Oui, vous devriez rejeter catégoriquement les entrées non valides.
  • Vous ne devriez pas permettre aux gens de polluer votre base de données avec des données corrompues.
  • Vous devriez n'essayez pas de nettoyer ces données au moment de l'affichage, pas plus que vous n'essaieriez de nettoyer <script> , car votre attaquant trouvera simplement un moyen d'exploiter votre nettoyage algorithme, comme <script > ou <scr<script>ipt> ou + ADw-script + AD4- ou autre.
  • Vous avez raison. il y a des exceptions, mais elles devraient être clairement définies comme cas particuliers: ils ne doivent pas être considérés comme la norme.
  • Sauf si vos exigences sont explicitement de traiter les devises suisses régionalisées avec des apostrophes en, votre exemple de "1'000'000" n'est pas plus un entier valide que " 1 ~ 000 ~ 000 "ou" 1banana000apple000 ". Rejetez-le. N'essayez pas de nettoyer "1'000", vous ne savez pas si cela signifie 1 000 ou 1 000 ou 14 000 ou un pied ou un degré ou quelque chose de complètement différent.

Le paramétrage des requêtes évite uniquement la plupart des classes injection SQL : pas tous les abus possibles de données invalides.

Mais qu'en est-il de tous les autres systèmes qui s'appuyer sur le nom d'utilisateur conforme à la norme de l'entreprise? Vous venez de les casser.

  • Les utilisateurs ont-ils des répertoires personnels? Cela va être un problème.
  • Est-ce que leurs noms sont enregistrés n'importe où?
  • Est-ce qu'ils sont jamais affichés?
  • Les noms d'utilisateur sont-ils jamais utilisés dans les paramètres de commande du système des appels?
  • Est-ce qu'ils envoient des données AJAX ou XML?
  • Y a-t-il des opérations en mode batch qui s'exécutent sur des lots de noms d'utilisateur, disons les noms commençant A à M un jour, N à Z le suivant, 0-9 le troisième jour, puis répétez? Ces lots ne fonctionneront jamais contre votre utilisateur '-_haxxor_-'.
  • Y a-t-il des cas où se faire passer pour un autre utilisateur serait nuisible ou utile pour quelqu'un, alors vous les voulez tous ont des noms uniques? Mais ils pourraient se faire passer pour l'utilisateur John en s'inscrivant comme quelque chose comme John Ϳο ո Јо հ ou Ꭻ օ.
  • Tous les systèmes qui utilisent le nom ne peuvent pas rejeter la valeur que vous avez donnée. Ils auront à la place pour gérer les entrées non valides, en essayant de les nettoyer ou de les échapper, même si nous avons déjà montré que ce n'est pas sécurisé et voué à l'échec. Mais comme l'utilisateur s'est déconnecté depuis longtemps, il ne verra aucune erreur demandant une nouvelle adresse e-mail.
  • Votre DBA a maintenant de la merde dans sa base de données. Cela lui causera beaucoup de peine, non seulement dans son travail quotidien, mais également lorsqu'il devra migrer ces données, car toute contrainte plus stricte dans le système cible sera rompue avec les anciennes données.
  • Vos collègues et les autres consommateurs de vos données doivent maintenant valider tout ce qu'ils lisent dans la base de données, car ils ne peuvent pas croire que vous avez appliqué même les normes entièrement documentées.
  • Vos utilisateurs utilisent maintenant un système moins sécurisé.
  • Vous devez maintenant retravailler toutes ces entrées pour vous assurer de ne plus nourrir de merde dans votre base de données.

Le paramétrage des requêtes n'est pas une alternative au nettoyage correct de vos entrées.

Laissez-nous [continuer cette discussion dans le chat] (https://chat.stackexchange.com/rooms/89352/discussion-between-dewi-morgan-and-lightness-races-in-orbit).
Il semble que mon commentaire a été supprimé lors d'un nettoyage de masse, je répète donc à ceux qui ne savent pas pourquoi cette réponse reçoit des votes négatifs: ** la désinfection de l'entrée ne remplace pas la gestion correcte des données en sortie **.Parmi les exemples donnés dans cette réponse, seul le cas d'emprunt d'identité est raisonnable à implémenter en entrée uniquement.Chacun des autres ne peut ** que ** être correctement traité en échappant ou en filtrant les données ** là où elles sont traitées **.La validation des entrées est utile pour donner des commentaires aux utilisateurs, mais elle ne fera qu'augmenter la sécurité si vous faites quelque chose de mal ailleurs.
@IMSoP: Vous vous disputez contre un homme de paille.Si vous pouvez mettre en évidence où vous avez la fausse croyance que j'ai dit que "la désinfection de l'entrée est un substitut à la gestion correcte de la sortie", alors je peux y remédier.MAIS JE N'AI PAS DIT CELA.Ce que j'ai dit, c'est que "le paramétrage des requêtes n'est pas une alternative à la désinfection correcte de vos entrées".Je l'ai même mis en gras, et tout.Les gens ne comprennent-ils pas la différence ici?Je trouve les implications sécuritaires d'une telle confusion plutôt effrayantes.
Le paramétrage des requêtes, * plus son équivalent partout où vous utilisez les données *, ** est ** une alternative à la désinfection des entrées;en effet, c'est une ** alternative supérieure ** si votre objectif est la sécurité.Il peut sembler rassurant de dire "votre nom d'utilisateur ne doit pas contenir d'apostrophe", mais tout ce qu'il dit à un attaquant est "qu'ils doivent l'utiliser dans une requête brute quelque part, je devrais trouver un moyen de les inciter à créer un utilisateur avec unapostrophe dans ".À moins d'être sûr à 100% que votre validation détecte tous les problèmes et qu'il n'y a aucun moyen de les contourner, vous devez vous défendre contre les mauvaises données lorsque vous les utilisez.
Fondamentalement, le problème du traitement de la désinfection des entrées comme une mesure de sécurité est qu'il n'existe pas de "données sécurisées";la sécurité dépend du contexte dans lequel vous l'utilisez.Puisque vous ne pouvez pas prédire tous les contextes possibles que vous allez avoir au cours de la durée de vie de vos données, vous pouvez soit limiter vos fonctionnalités et votre utilisabilité en restreignant chaque champ à A-Z, a-z, 0-9;ou vous pouvez traiter la désinfection comme une mesure incomplète soutenue par la «vraie» sécurité écrite dans chaque contexte tel qu'il est rencontré.
@IMSoP: La validation, le paramétrage et l'échappement de sortie sont les trois axes orthogonaux de la sécurité des entrées utilisateur.L'absence de l'un d'entre eux est une faille de sécurité.Les débordements de tampon, les débordements d'entiers, le problème de plage de traitement par lots cron que j'ai décrit et d'innombrables attaques d'exécution de code arbitraire sont atténués par une validation correcte et multicouche, mais ne sont absolument pas affectés par les deux autres axes.
Je ne vois pas comment le problème de dosage par plage serait "non affecté par les deux autres axes".** Si ** vous savez que vous pouvez faire confiance à 100% à toutes les entrées comme étant alphanumériques, l'algorithme décrit est acceptable;mais dans le cas fort probable que ce n'est pas le cas, vous devez ajouter une assertion qui alerte un opérateur, ou une clause "et tout autre chose".Ainsi, la solution la plus sûre est celle qui se rapproche le plus du traitement, et non celle qui fait confiance à un formulaire d'entrée 10 ans auparavant pour avoir prédit le scénario.
serait -1 si je pouvais ... "Aucun pentester digne de leur sel n'aurait ..." La question n'est-elle pas de déterminer si le pentester vaut son sel?"Pentester a dit X, sont-ils corrects?"En supposant que le pentester n'a pas réellement dit «X», cela passe complètement à côté.
"Si vous pouvez mettre en évidence où vous avez eu la fausse croyance que j'ai dit" la désinfection de l'entrée est un substitut à la gestion correcte de la sortie "," - Cette citation: "Mais qu'en est-il de tous les autres systèmes qui reposent sur le nom d'utilisateur conforme à la norme de l'entreprise"Vous venez de les casser."déclare concrètement que les systèmes qui utilisent l'entrée de cette application se casseront _parce_ que cette application ne nettoie pas.(L'alternative est qu'ils ne se briseront pas s'ils désinfectent.) L'implication forte ici est que l'assainissement est la seule couche de défense.


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 4.0 sous laquelle il est distribué.
Loading...