PCRE & sécurité

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : PCRE & sécurité

par naholyr » 15 juil. 2007, 12:08

J'utilise donc preg_replace, et je disais que la première chose que j'ai fait, c'est d'empêcher l'utilisation de l'option e (qui permettrait aux utilisateurs d'exécuter n'importe quelle action en php). Seulement j'aimerai savoir s'il n'y a pas d'autres options (ou je ne sais quoi) qui permettraient à des utilisateurs malveillants (ou maladroits) de causer des quelconques problèmes autres que les erreurs d'interprétation de la regex qu'ils ont écrit...
En sécurité la première règle c'est «tout interdire, et autoriser au cas par cas».
Donc plutôt que de te poser la question de «quelles options pourraient poser problème ?» demande-toi plutôt quelles options ne peuvent pas en poser, et n'autoriser que celles-là.

Pour le masque en lui-même, toujours le même raisonnement : je ne laisserais pas l'utilisateur entrer son propre délimiteur. Cela évite d'avoir à se demander quel délimiteur risque de poser problème. J'en fixe un, et l'utilisateur s'y conforme.

Ainsi l'entrée du masque se ferait avec deux champs :

Code : Tout sélectionner

/ [ . . . ] / [ . . . ]
L'utilisateur entre son masque, sans les délimiteurs (qui sont fixés à '/') dans le premier champ, et ses options dans le deuxième champ.
Si tu n'as décidé d'autoriser que les options 's', 'i', et 'm', alors tout ce qui n'est pas 's', 'i', ou 'm' sera simplement ignoré ou sera la cause de l'affichage d'un message d'erreur.

par Ripat » 15 juil. 2007, 10:08

preg_replace_callback() est sûre en soi. Tout va dépendre de ton code en amont ou en aval

Pour le reste de ton code, précautions habituelles contre les injections classiques:
  • injections SQL
  • mail header (fonction mail())
  • eval() exec() passthru() et compagnie (injection shell)
  • preg_replace option e
  • $_GET $_POST non validés
  • include() et require()
  • ...

par o7a.net » 14 juil. 2007, 21:58

inutile d'argumenter pour preg_replace_callback, je suis totalement convaincu de ses avantages devant l'option e de preg_replace !

En fait, ce que je souhaite faire, c'est permettre aux utilisateurs de donner la regex, le replacement string, et la chaine de caractères à laquelle on applique les modifications (puis le résultat leur est renvoyé).

J'utilise donc preg_replace, et je disais que la première chose que j'ai fait, c'est d'empêcher l'utilisation de l'option e (qui permettrait aux utilisateurs d'exécuter n'importe quelle action en php). Seulement j'aimerai savoir s'il n'y a pas d'autres options (ou je ne sais quoi) qui permettraient à des utilisateurs malveillants (ou maladroits) de causer des quelconques problèmes autres que les erreurs d'interprétation de la regex qu'ils ont écrit...

D'après la doc de php.net, je ne vois rien d'autre que l'option e, mais pour m'en assurer j'aimerai votre avis.

par Ripat » 14 juil. 2007, 18:23

Pour l'option e et callback, je cherche justement à me débarrasser de l'insertion de php puisque je dois permettre aux utilisateurs d'entrer eux même les regexes.
Le problème de preg_replace() avec l'option e est que le replacement string est évalué comme du code PHP ---> DANGER!
e force preg_replace() à traiter replacement comme du code PHP une fois que les substitutions adéquates ont été faites.
Alors qu'avec preg_replace_callback(), le replacement string est traité classiquement par le moteur regex sans évaluation par PHP. Les captures sont envoyées vers la fonction en callback où elles seront traitées selon les besoins, à nouveau sans évaluation de code PHP.

De plus, preg_replace() option e est totalement illisible (la valse des guillemets!).
// L'exemple de la doc:

preg_replace("/(<\/?)(\w+)([^>]*>)/e",
              "'\\1'.strtoupper('\\2').'\\3'",
              $html_body);

// avec preg_replace_callback

function maFonction ($capture) {
  return $capture[1] . strtoupper($capture[2]) . $capture[3];
}

preg_replace_callback("/(<\/?)(\w+)([^>]*>)/",
              'maFonction',
              $html_body);

Un peu plus verbeux mais tellement plus simple et plus sécuritaire. Et beaucoup plus rapide.

par o7a.net » 14 juil. 2007, 15:43

Voilà qui est clair, pour les marqueurs, merci pour l'info.

Pour l'option e et callback, je cherche justement à me débarrasser de l'insertion de php puisque je dois permettre aux utilisateurs d'entrer eux même les regexes.

par Ripat » 14 juil. 2007, 14:11

Hello,

1) Tout caractère non alphanum à l'exception du backslash. Plus, assez curieusement, les caractères ouvrant/fermant tels que [{(<. C'est une curiosité PHP car je ne connais aucun autre language qui les accepte comme délimiteur. Ainsi les masques suivants sont corrects:
  • Délimiteurs classiques
    /masque/
    #masque#
    `masque`
    !masque!
    .masque.
    %masque%
  • Délimiteurs exotiques (pas recommandé car difficilement lisible pour tout esprit "regex" normalement constitué!)
    [masque]
    <masque>
    (masque)
    {masque}
2) Option e: préférer de loin preg_replace_callback(), plus lisible et performante.

par o7a.net » 13 juil. 2007, 14:18

Autrement dit l'article dit qu'il est impossible de permettre l'insertion de regexes par les utilisateurs sans failles de sécurité...

preg_quote ne convient pas puisque sans les caractères spéciaux, l'insertion de regexes perd tout son intérêt...

Créer son propre langage ... ça ne me fait pas peur mais il ne sera dans tous les cas pas aussi complet que PCRE, et rien ne dit que ce langage ne laissera pas lui aussi des failles de sécurité (surtout si je ne sais même pas quelles sont les failles de PCRE).

Ce que j'aimerais savoir, c'est outre l'option e, quelles peuvent être ces failles ? ... à l'exception des erreurs dans l'interprétation de la regex (erreurs de syntaxe, boucles infinies ...) qui, cela dit, peuvent être gérées sans poser de problèmes de sécurité ...

merci pour ton aide Mandar.

par Mandar » 12 juil. 2007, 14:39

J'avais pas vu ce sujet.
Un article qui devrait t'intéresser.

PCRE & sécurité

par o7a.net » 27 juin 2007, 02:37

Bonjour,

J'aurais deux questions à propos des PCRE...

1) Est-ce qu'il existe une liste exhaustive des marqueurs supportés par pcre pour encadrer les regex ?

2) Quelles sont les sécurités à prendre si on veut permettre l'utilisation de regexes par les utilisateurs via une interface quelconque ? Plus précisément si on veut leur permettre de renseigner les trois premiers attributs de preg_replace (la regex, son remplacement, et la chaine de caractères à laquelle on applique les changements) ; je pense notamment à l'option e qui permet d'exécuter n'importe quelle fonction php, ce qui est très risqué.

Merci pour votre attention.