.\" Automatically generated by Pod::Man 2.09 (Pod::Simple 3.04) .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "PERLSEC 1" .TH PERLSEC 1 "2006-03-21" "DocFr" "User Contributed Perl Documentation" .SH "NAME/NOM" .IX Header "NAME/NOM" perlsec \- Se\*'curite\*' de Perl .SH "DESCRIPTION" .IX Header "DESCRIPTION" Perl est conc\*,u pour faciliter une programmation su\*^re, me\*^me lorsqu'il tourne avec des privile\*`ges spe\*'ciaux, comme pour les programmes setuid ou setgid. Contrairement a\*` la plupart des shells de ligne de commande, qui sont base\*'s sur de multiples passes de substitution pour chaque ligne du script, Perl utilise un proce\*'de\*' d'e\*'valuation plus conventionnel contenant moins de pie\*`ges cache\*'s. De plus, comme le langage a plus de fonctionnalite\*'s inte\*'gre\*'es, il doit moins se reposer sur des programmes externes (et potentiellement peu su\*^rs) pour accomplir ses ta\*^ches. .PP Perl met en oeuvre automatiquement un ensemble de ve\*'rifications spe\*'cifiques a\*` la se\*'curite\*', appele\*' \fItaint mode\fR (mode souille\*', \s-1NDT\s0), lorsqu'il de\*'tecte que son programme tourne avec des identifiants de groupe ou d'utilisateurs re\*'el et effectif diffe\*'rents. Le bit setuid dans les permissions d'Unix est le mode 04000, le bit setgid est le mode 02000 ; ils peuvent e\*^tre place\*'s l'un ou l'autre, ou les deux a\*` la fois. Vous pouvez aussi activer le taint mode explicitement en utilisant l'option de ligne de commande \fB\-T\fR. Cette option est \&\fIfortement\fR conseille\*'e pour les programmes serveurs et pour tout programme exe\*'cute\*' au nom de quelqu'un d'autre, comme un script \&\s-1CGI\s0. Une fois que le taint mode est active\*', il l'est pour tout le reste de votre script. .PP Lorsqu'il est dans ce mode, Perl prend des pre\*'cautions spe\*'ciales appele\*'es \fItaint checks\fR (ve\*'rification de pollution, \s-1NDT\s0) pour e\*'viter aussi bien les pie\*`ges e\*'vidents que les pie\*`ges subtils. Certaines de ces ve\*'rifications sont raisonnablement simples, comme ve\*'rifier que personne ne peut e\*'crire dans les re\*'pertoires du path ; les programmeurs pre\*'cautionneux ont toujours utilise\*' de telles me\*'thodes. D'autres ve\*'rifications, toutefois, sont mieux supporte\*'es par le langage lui\-me\*^me, et ce sont ces ve\*'rifications en particulier qui contribuent a\*` rendre un programme Perl set-id plus su\*^r qu'un programme e\*'quivalent en C. .PP Vous ne pouvez pas utiliser des donne\*'es provenant de l'exte\*'rieur de votre programme pour modifier quelque chose d'autre a\*` l'exte\*'rieur \*(-- au moins pas par accident. Tous les arguments de ligne de commande, toutes les variables d'environnement, toutes les informations locales (voir perllocale), re\*'sultant de certains appels au syste\*`me (\f(CW\*(C`readdir()\*(C'\fR, \f(CW\*(C`readlink()\*(C'\fR, la variable de \f(CW\*(C`shmread()\*(C'\fR, les messages renvoye\*'s par \f(CW\*(C`msgrcv()\*(C'\fR, le mot de passe, les champs gecos et shell des appels \f(CW\*(C`getpwxxx()\*(C'\fR), et toutes les entre\*'es par fichier sont marque\*'es comme \*(L"souille\*'es\*(R". Les donne\*'es souille\*'es ne peuvent pas e\*^tre utilise\*'es directement ou indirectement dans une commande qui invoque un sous\-shell, ni dans toute commande qui modifie des fichiers, des re\*'pertoires ou des processus, \fBavec les exceptions suivantes\fR\ : .IP "\(bu" 4 Les fonctions \f(CW\*(C`print\*(C'\fR et \f(CW\*(C`syswrite\*(C'\fR \fBne\fR ve\*'rifient \fBpas\fR si leurs arguments sont souille\*'es ou non. .IP "\(bu" 4 La su\*^rete\*' des valeurs utilise\*'es comme me\*'thodes symboliques .Sp .Vb 1 \& $obj\->$method(@args); .Ve .Sp ou comme re\*'fe\*'rences symboliques a\*` des sous-programmes .Sp .Vb 2 \& &{$foo}(@args); \& $foo\->(@args); .Ve .Sp n'est pas ve\*'rifie\*'e. Cela ne\*'cessite une attention particulie\*`re a\*` moins que vous acceptiez que des donne\*'es externes affectent votre flux de contro\*^le. Si vous ne limitez pas tre\*`s pre\*'cise\*'ment ce que seront ces valeurs symboliques, les personnes les fournissant pourront appeler des fonctions \fBen dehors\fR de votre code Perl, telle que POSIX::system, et seront donc a\*` me\*^me d'exe\*'cuter n'importe quel code externe. .PP Pour des raisons d'efficacite\*', Perl a un point de vue tre\*`s conservateur sur ce qui est souille\*' ou non. Si une expression contient des donne\*'es souille\*'es, n'importe quelle sous-expression sera conside\*'re\*'e comme souille\*'e, me\*^me si la valeur de cette sous-expression n'est pas affecte\*'e par des donne\*'es souille\*'es. .PP Puisque la su\*^rete\*' est associe\*'e a\*` chaque valeur scalaire, certains e\*'le\*'ments d'un tableau peuvent e\*^tre souille\*'s et d'autres pas. Les cle\*'s d'une table de hachage ne sont jamais souille\*'es. .PP Par exemple\ : .PP .Vb 8 \& $arg = shift; # $arg est souille\*'e \& $hid = $arg, 'bar'; # $hid est aussi souille\*'e \& $line = <>; # Souille\*'e \& $line = ; # Souille\*'e aussi \& open FOO, "/home/me/bar" or die $!; \& $line = ; # Encore souille\*'e \& $path = $ENV{'PATH'}; # Souille\*'e, mais voir plus bas \& $data = 'abc'; # Non souille\*'e \& \& system "echo $arg"; # Non su\*^r \& system "/bin/echo", $arg; # Conside\*'re\*' comme non su\*^r \& # (Perl ne sait rien de /bin/echo) \& system "echo $hid"; # Non su\*^r \& system "echo $data"; # Non su\*^r jusqu'a\*` ce que PATH soit fixe\*' \& \& $path = $ENV{'PATH'}; # $path est de\*'sormais souille\*'e \& \& $ENV{'PATH'} = '/bin:/usr/bin'; \& delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; \& \& $path = $ENV{'PATH'}; # $path N'est maintenant PLUS souille\*'e \& system "echo $data"; # Est de\*'sormais su\*^r ! \& \& open(FOO, "< $arg"); # ok \- fichier en lecture seule \& open(FOO, "> $arg"); # Pas ok \- tentative d'e\*'criture \& \& open(FOO,"echo $arg|"); # Pas ok \& open(FOO,"\-|") \& or exec 'echo', $arg; # Pas ok non plus \& \& $shout = `echo $arg`; # Non su\*^r, $shout est maintenant souille\*'e \& \& unlink $data, $arg; # Non su\*^r \& umask $arg; # Non su\*^r \& \& exec "echo $arg"; # Non su\*^r \& exec "echo", $arg; # Non su\*^r \& exec "sh", '\-c', $arg; # Extre\*^mement non su\*^r ! \& \& @files = <*.c>; # Non su\*^r (utilise readdir() ou e\*'quivalent) \& @files = glob('*.c'); # Non su\*^r (utilise readdir() ou e\*'quivalent) \& \& # Les versions de Perl ante\*'rieures a\*` 5.6.0 utilisaient un programme \& # externe pour trouver les noms de fichiers dans <*.c> ou glob('*.c'). \& # Mais dans tous les cas, le re\*'sultat est souille\*' puisque la liste des \& # noms de fichiers provient de l'exte\*'rieur du programme. \& \& $bad = ($arg, 23); # $bad est souille\*' \& $arg, `true`; # Non su\*^r (me\*^me si c\*,a ne l'est pas) .Ve .PP Si vous essayez de faire quelque chose qui n'est pas su\*^r, vous obtiendrez une erreur fatale disant quelque chose comme \*(L"Insecure dependency\*(R" ou \*(L"Insecure \f(CW$ENV\fR{\s-1PATH\s0}\*(R". .PP L'exception a\*` la re\*`gle \*(L"une valeur souille\*'e souille l'ensemble de l'expression\*(R" est l'ope\*'rateur ternaire conditionnel \f(CW\*(C`?:\*(C'\fR. Puisque le code utilisant l'ope\*'rateur conditionnel\ : .PP .Vb 1 \& $result = $valeur_souillee ? "Pas souille\*'" : "Pas souille\*' non plus"; .Ve .PP est en fait\ : .PP .Vb 5 \& if ($valeur_souillee) { \& $result = "Pas souille\*'"; \& } else { \& $result = "Pas souille\*' non plus"; \& } .Ve .PP cela n'aurait pas beaucoup de sens de souille\*' \f(CW$result\fR. .Sh "Blanchiement et de\*'tection des donne\*'es souille\*'es" .IX Subsection "Blanchiement et de'tection des donne'es souille'es" Pour tester si une variable contient des donne\*'es souille\*'es, et quels usages provoqueraient ainsi un message \*(L"Insecure dependency\*(R", vous pouvez utiliser la fonction \f(CW\*(C`tainted()\*(C'\fR du module Scalar::Util, disponible sur \s-1CPAN\s0 ou inclus dans Perl depuis la version 5.8.0. Ou vous pouvez utiliser la fonction \f(CW\*(C`is_tainted\*(C'\fR suivante\ : .PP .Vb 3 \& sub is_tainted { \& return ! eval { eval("#" . substr(join('', @_), 0, 0)); 1; }; \& } .Ve .PP Cette fonction utilise le fait que la pre\*'sence de donne\*'es souille\*'es n'importe ou\*` dans une expression rend toute l'expression souille\*'e. Il serait inefficace de tester la su\*^rete\*' de tous les arguments pour tous les ope\*'rateurs. Au lieu de cela, l'approche le\*'ge\*`rement plus efficace et conservatrice qui est utilise\*'e est que si une valeur souille\*'e a e\*'te\*' acce\*'de\*'e a\*` l'inte\*'rieur d'une expression, alors la totalite\*' de l'expression est conside\*'re\*'e comme souille\*'e. .PP Mais le test de purete\*' ne vous fournit rien d'autre. Parfois, vous devez juste rendre vos donne\*'es propres. Une valeur peut e\*^tre blanchie en l'utilisant comme cle\*' de table de hachage. Sinon, la seule fac\*,on d'outrepasser le me\*'canisme de pollution est de re\*'fe\*'rencer des sous-motifs depuis une expression re\*'gulie\*`re. Perl pre\*'sume que si vous re\*'fe\*'rencez une sous\-chai\*^ne en utilisant \f(CW$1\fR, \f(CW$2\fR, etc., c'est que vous saviez ce que vous e\*'tiez en train de faire lorsque vous re\*'digiez le motif. Cela implique un peu de re\*'flexion \*(-- ne blachissez pas tout aveugle\*'ment, ou vous de\*'truisez la totalite\*' du me\*'canisme. Il est meilleur de ve\*'rifier que la variable ne contient que des bons caracte\*`res (pour certaines valeurs de \*(L"bon\*(R") pluto\*^t que de ve\*'rifier qu'elle contient un quelconque mauvais caracte\*`re. C'est parce qu'il est beaucoup trop facile de manquer un mauvais caracte\*`re auquel vous n'avez jamais pense\*'. .PP Voici un test pour s'assurer que les donne\*'es ne contiennent rien d'autre que des caracte\*`res de \*(L"mots\*(R" (alphabe\*'tiques, nume\*'riques et souligne\*'), un tiret, une arobase, ou un point. .PP .Vb 5 \& if ($data =~ /^([\-\e@\ew.]+)$/) { \& $data = $1; # $data est maintenant propre \& } else { \& die "Bad data in '$data'"; # tracer cela quelque part \& } .Ve .PP Ceci est assez su\*^r car \f(CW\*(C`/\ew+/\*(C'\fR ne correspond normalement pas aux me\*'tacaracte\*`res du shell, et les points, tirets ou arobases ne veulent rien dire de spe\*'cial pour le shell. L'usage de \f(CW\*(C`/.+/\*(C'\fR n'aurait pas e\*'te\*' su\*^r en the\*'orie parce qu'il laisse tout passer, mais Perl ne ve\*'rifie pas cela. La lec\*,on est que lorsque vous blanchissez, vous devez e\*^tre excessivement pre\*'cautionneux avec vos motifs. Le blanchiment des donne\*'es a\*` l'aide d'expressions re\*'gulie\*`res est le \&\fIseul\fR me\*'canisme pour nettoyer les donne\*'es pollue\*'es, a\*` moins que vous n'utilisiez la strate\*'gie de\*'taille\*'e ci-dessous pour forker un fils ayant des privile\*`ges plus faibles. .PP L'exemple ne nettoie pas \f(CW$data\fR si \f(CW\*(C`use locale\*(C'\fR est en cours d'utilisation, car les caracte\*`res auxquels correspond \f(CW\*(C`\ew\*(C'\fR sont de\*'termine\*'s par la localisation. Perl conside\*`re que les de\*'finitions locales ne sont pas su\*^res car elles contiennent des donne\*'es exte\*'rieures au programme. Si vous e\*'crivez un programme conscient de la localisation, et si voulez blanchir des donne\*'es avec une expression re\*'gulie\*`re contenant \f(CW\*(C`\ew\*(C'\fR, mettez \f(CW\*(C`no locale\*(C'\fR avant l'expression dans le me\*^me bloc. Voir \*(L"SE\*'CURITE\*'\*(R" in perllocale pour plus de pre\*'cisions et des exemples. .ie n .Sh "Options sur la ligne ""#!""" .el .Sh "Options sur la ligne ``#!''" .IX Subsection "Options sur la ligne #!" Quand vous rendez un script exe\*'cutable, de fac\*,on a\*` pouvoir l'utiliser comme une commande, le syste\*`me passera des options a\*` perl a\*` partir de la ligne #! du script. Perl ve\*'rifie que toutes les options de ligne de commande donne\*'es a\*` un script setuid (ou setgid) correspondent effectivement a\*` celles place\*'es sur la ligne #!. Certains Unix et environnements cousins imposent une limite d'une seule option sur la ligne #!, vous aurez donc peut\-e\*^tre besoin d'utiliser quelque chose comme \f(CW\*(C`\-wU\*(C'\fR a\*` la place de \f(CW\*(C`\-w \-U\*(C'\fR sous ces syste\*`mes (ce proble\*`me ne devrait se poser qu'avec les Unix et les environnement proches qui supportent #! et les scripts setuid ou setgid). .ie n .Sh "Mode taint et @INC" .el .Sh "Mode taint et \f(CW@INC\fP" .IX Subsection "Mode taint et @INC" Lorsque le mode \*(L"taint\*(R" (\f(CW\*(C`\-T\*(C'\fR) est actif, le re\*'pertoire \*(L".\*(R" ne fait plus partie de \f(CW@INC\fR et les variables d'environnement \f(CW\*(C`PERL5LIB\*(C'\fR et \&\f(CW\*(C`PERLLIB\*(C'\fR sont ignore\*'es par Perl. Vous pouvez encore modifier \f(CW@INC\fR depuis l'exte\*'rieur du programme en utilisant l'option \f(CW\*(C`\-I\*(C'\fR de la ligne de commande comme explique\*' dans perlrun. Les deux variables d'environnement sont ignore\*'es parce qu'elles sont cache\*'es et qu'un utilisateur qui lance un programme ne sait pas obligatoirement qu'elles existent alors que l'option \f(CW\*(C`\-I\*(C'\fR est clairement visible et peut donc e\*^tre tole\*'re\*'e. .PP Un autre moyen de modifier \f(CW@INC\fR sans modifier le programme consiste a\*` utiliser la directive \f(CW\*(C`lib\*(C'\fR de la manie\*`re suivante\ : .PP .Vb 1 \& perl \-Mlib=/foo programme .Ve .PP L'avantage de \f(CW\*(C`\-Mlib=/foo\*(C'\fR sur \f(CW\*(C`\-I/foo\*(C'\fR est de ge\*'rer les e\*'ventuelles occurences multiples d'un me\*^me re\*'pertoire (le re\*'pertoire ne sera pas re\*'pe\*'te\*' dans \f(CW@INC\fR). .PP Notez que si un chemin souille\*' est ajoute\*' a\*` \f(CW@INC\fR, le proble\*`me suivant sera de\*'tecte\*'\ : .PP .Vb 1 \& Insecure dependency in require while running with \-T switch .Ve .Sh "Nettoyer votre \s-1PATH\s0" .IX Subsection "Nettoyer votre PATH" Pour les messages "Insecure \f(CW$ENV{PATH}\fR", vous avez besoin de fixer \&\f(CW$ENV{'PATH'}\fR a\*` une valeur connue, et chaque re\*'pertoire dans le \s-1PATH\s0 doit e\*^tre spe\*'cifie\*' sous la forme d'un chemin absolu et non modifiable par d'autres utilisateurs que son proprie\*'taire et son groupe. Vous pourriez e\*^tre surpris d'obtenir ce message alors me\*^me que le chemin vers votre exe\*'cutable est un chemin absolu. Ceci n'est \fIpas\fR ge\*'ne\*'re\*' parce que vous n'avez pas fourni un chemin complet au programme mais pluto\*^t parce que vous n'avez jamais de\*'fini votre variable d'environnement \s-1PATH\s0, ou vous ne l'avez pas de\*'fini comme quelque chose de su\*^r. Puisque Perl ne peut pas garantir que l'exe\*'cutable en question ne vas pas exe\*'cuter un autre programme qui de\*'pend de votre \s-1PATH\s0, il s'assure que vous avez de\*'fini le \s-1PATH\s0. .PP Le \s-1PATH\s0 n'est pas la seule variable d'environnement qui peut poser des proble\*`mes. Puisque certains shells peuvent utiliser les variables \&\s-1IFS\s0, \s-1CDPATH\s0, \s-1ENV\s0, et \s-1BASH_ENV\s0, Perl ve\*'rifie que celles-ci sont soit vides, soit propres, lorsqu'il de\*'marre des sous\- processus. Vous pourriez de\*'sirer ajouter quelque chose comme ceci a\*` vos scripts setid et blanchisseurs. .PP .Vb 1 \& delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Rend %ENV plus su\*^r .Ve .PP Il est aussi possible de s'attirer des ennuis avec d'autres ope\*'rations qui ne se soucient pas si elles utilisent des valeurs souille\*'es. Faites un usage judicieux des tests de fichiers quand vous avez affaire a\*` un nom de fichier fournis par l'utilisateur. Lorsque c'est possible, re\*'alisez les ouvertures et compagnie \fBapre\*`s\fR avoir correctement abandonne\*' les privile\*`ges d'utilisateur (ou de groupe !) particuliers. Perl ne vous empe\*^che pas d'ouvrir en lecture des noms de fichier souille\*'s, alors faites attention a\*` ce que vous imprimez. Le me\*'canisme de pollution est destine\*' a\*` pre\*'venir les erreurs stupides, pas a\*` supprimer le besoin de re\*'flexion. .PP Perl n'appelle pas de shell pour expanser les me\*'tacaracte\*`res (wildcards, \s-1NDT\s0) quand vous passez des listes de parame\*`tres explicites a\*` \f(CW\*(C`system\*(C'\fR et \f(CW\*(C`exec\*(C'\fR au lieu de chai\*^nes pouvant contenir des me\*'tacaracte\*`res. Malheureusement, les fonctions \f(CW\*(C`open\*(C'\fR, \f(CW\*(C`glob\*(C'\fR, et backtick (substitution de commande avec \*(L"`\*(R", \s-1NDT\s0) ne fournissent pas de telles conventions d'appel alternatives, alors d'autres subterfuges sont requis. .PP Perl fournit une fac\*,on raisonnablement su\*^re d'ouvrir un fichier ou un tube depuis un programme setuid ou setgid\ : cre\*'ez juste un processus fils ayant des privile\*`ges re\*'duits et qui fera le sale boulot pour vous. Tout d'abord, cre\*'ez un fils en utilisant la syntaxe spe\*'ciale de \&\f(CW\*(C`open\*(C'\fR qui connecte le pe\*`re et le fils par un tube. Puis le fils rede\*'finit son ensemble d'\s-1ID\s0 et tous les autres attributs de\*'pendant du processus, comme les variables d'environnement, les umasks, les re\*'pertoires courants, pour retourner a\*` des valeurs originelles ou connues comme su\*^res. Puis le processus fils, qui n'a plus la moindre permission spe\*'ciale, re\*'alise le \f(CW\*(C`open\*(C'\fR ou d'autres appels syste\*`me. Finalement, le fils passe a\*` son pe\*`re les donne\*'es auxquelles il parvient a\*` acce\*'der. Puisque le fichier ou le tube ont e\*'te\*' ouverts par le fils alors qu'il tournait avec des privile\*`ges infe\*'rieurs a\*` celui du pe\*`re, il ne peut pas e\*^tre trompe\*' et faire quelque chose qu'il ne devrait pas. .PP Voici une fac\*,on de faire des substitutions de commande de fac\*,on raisonnablement su\*^re. Remarquez comment le \f(CW\*(C`exec\*(C'\fR n'est pas appele\*' avec une chai\*^ne que le shell pourrait interpre\*'ter. C'est de loin la meilleure manie\*`re d'appeler quelque chose qui pourrait e\*^tre sujet a\*` des se\*'quences d'e\*'chappements du shell\ : n'appelez tout simplement jamais le shell. .PP .Vb 10 \& use English '\-no_match_vars'; \& die "Can't fork: $!" unless defined($pid = open(KID, "\-|")); \& if ($pid) { # parent \& while () { \& # faire quelque chose \& } \& close KID; \& } else { \& my @temp = ($EUID, $EGID); \& my $orig_uid = $UID; \& my $orig_gid = $GID; \& $EUID = $UID; \& $EGID = $GID; \& # suppression des privile\*`ges \& $UID = $orig_uid; \& $GID = $orig_gid; \& # S'assurer que les privile\*`ges sont re\*'ellement partis \& ($EUID, $EGID) = @temp; \& die "Can't drop privileges" \& unless $UID == $EUID && $GID eq $EGID; \& $ENV{PATH} = "/bin:/usr/bin"; # PATH minimaliste \& exec 'myprog', 'arg1', 'arg2' \& or die "can't exec myprog: $!"; \& } .Ve .PP Une strate\*'gie similaire marcherait pour l'expansion des me\*'tacaracte\*`res via \f(CW\*(C`glob\*(C'\fR, bien que vous pouvez utiliser \f(CW\*(C`readdir\*(C'\fR a\*` la place. .PP La ve\*'rification de la su\*^rete\*' est surtout utile lorsque, me\*^me si vous vous faites confiance de ne pas avoir e\*'crit un programme ouvrant toutes les portes, vous ne faites pas ne\*'cessairement confiance a\*` ceux qui finiront par l'utiliser et pourraient essayer de le tromper pour qu'il fasse de vilaines choses. C'est le genre de ve\*'rification de se\*'curite\*' qui est utile pour les programmes set-id et les programmes qui sont lance\*'s au nom de quelqu'un d'autre, comme les scripts \s-1CGI\s0. .PP C'est tre\*`s diffe\*'rent, toutefois, du cas ou\*` l'on ne fait me\*^me pas confiance a\*` l'auteur du code de ne pas essayer de faire quelque chose de diabolique. Ceci est le type de confiance dont on a besoin quand quelqu'un vous tend un programme que vous n'avez jamais vu auparavant et vous dit\ : \*(L"Voila\*`, exe\*'cute ceci\*(R". Pour ce genre de se\*'curite\*', jetez un oeil au module Safe, inclu en standard dans la distribution de Perl. Ce module permet au programmeur de mettre en place des compartiments spe\*'ciaux dans lesquels toutes les ope\*'rations lie\*'es au syste\*`me sont de\*'tourne\*'es et ou\*` l'acce\*`s a\*` l'espace de noms est contro\*^le\*' avec soin. .Sh "Failles de se\*'curite\*'" .IX Subsection "Failles de se'curite'" Au\-dela\*` des proble\*`mes e\*'vidents qui de\*'coulent du fait de donner des privile\*`ges spe\*'ciaux a\*` des syste\*`mes aussi flexibles que les scripts, sous de nombreuses versions d'Unix, les scripts set-id ne sont pas su\*^rs de\*`s le de\*'part de fac\*,on inhe\*'rente. Le proble\*`me est une race condition dans le noyau. Entre le moment ou\*` le noyau ouvre le fichier pour voir quel interpre\*'teur il doit exe\*'cuter et celui ou\*` l'interpre\*'teur (maintenant set\-id) se retourne et re\*'ouvre le fichier pour l'interpre\*'ter, le fichier en question peut avoir change\*', en particulier si vous avez des liens symboliques dans votre syste\*`me. .PP Heureusement, cette \*(L"caracte\*'ristique\*(R" du noyau peut parfois e\*^tre invalide\*'e. Malheureusement, il y a deux fac\*,ons de l'invalider. Le syste\*`me peut simplement de\*'clarer hors-la-loi les scripts ayant un bit set-id mis, ce qui n'aide pas vraiment. Sinon, il peut simplement ignorer les bits set-id pour les scripts. Si ce dernier cas est vrai, Perl peut e\*'muler le me\*'canisme setuid et setgid lorsqu'il remarque les bits setuid/gid bits, par ailleurs inutiles, sur des scripts Perl. Il le fait via un exe\*'cutable spe\*'cial appele\*' \fIsuidperl\fR qui est appele\*' automatiquement pour vous si besoin est. .PP Toutefois, si la caracte\*'ristique du noyau pour les scripts set-id n'est pas invalide\*'e, Perl se plaindra bruyamment que votre script set-id n'est pas su\*^r. Vous devrez soit invalider la caracte\*'ristique du noyau pour les scripts set\-id, soit mettre un wrapper C autour du script. Un wrapper C est juste un programme compile\*' qui ne fait rien a\*` part appeler votre programme Perl. Les programmes compile\*'s ne sont pas sujets au bug du noyau qui tourmente les scripts set\-id. Voici un wrapper simple, e\*'crit en C\ : .PP .Vb 6 \& #define REAL_PATH "/path/to/script" \& main(ac, av) \& char **av; \& { \& execv(REAL_PATH, av); \& } .Ve .PP Compilez ce wrapper en un binaire exe\*'cutable, puis rendez\-\fIit\fR setuid ou setgid a\*` la place de votre script. .PP Ces dernie\*`res anne\*'es, les vendeurs ont commence\*' a\*` fournir des syste\*`mes libe\*'re\*'s de ce bug de se\*'curite\*' inhe\*'rent. Sur de tels syste\*`mes, lorsque le noyau passe le nom du script set-id a\*` ouvrir a\*` l'interpre\*'teur, pluto\*^t que d'utiliser un nom et un chemin sujets a\*` l'inge\*'rence, il passe \fI/dev/fd/3\fR. C'est un fichier spe\*'cial de\*'ja\*` ouvert sur le script, de sorte qu'il ne peut plus y avoir de race condition que des scripts malins pourraient exploiter. Sur ces syste\*`mes, Perl devrait e\*^tre compile\*' avec l'option \f(CW\*(C`\-DSETUID_SCRIPTS_ARE_SECURE_NOW\*(C'\fR. Le programme \fIConfigure\fR qui construit Perl essaye de trouver cela tout seul, vous ne devriez donc jamais avoir a\*` spe\*'cifier cela vous\-me\*^me. La plupart des versions modernes de SysVr4 et \s-1BSD\s0 4.4 utilisent cette approche pour e\*'viter la race condition du noyau. .PP Avant la version 5.6.1 de Perl, des bugs dans le code de \fBsuidperl\fR pouvait introduire des failles de se\*'curite\*'. .Sh "Protection de vos programmes" .IX Subsection "Protection de vos programmes" Il existe de nombreuses fac\*,ons de cacher le source de vos programmes Perl, avec des niveaux variables de \*(L"se\*'curite\*'\*(R". .PP Tout d'abord, toutefois, vous \fIne\fR pouvez \fIpas\fR retirer la permission en lecture, car le code source doit e\*^tre lisible de fac\*,on a\*` e\*^tre compile\*' et interpre\*'te\*' (cela ne veut toutefois pas dire que le source d'un script \s-1CGI\s0 est lisible par n'importe qui sur le web). Vous devez donc laisser les permissions au niveau socialement amical de 0755. Ceci laisse voir votre source uniquement aux gens de votre syste\*`me local. .PP Certaines personnes prennent par erreur ceci pour un proble\*`me de se\*'curite\*'. Si votre programme fait des choses qui ne sont pas su\*^res, et s'appuie sur le fait que les gens ne savent pas comment exploiter ces failles, il n'est pas su\*^r. Il est souvent possible pour quelqu'un de de\*'terminer les failles de se\*'curite\*' et de les exploiter sans voir le source. La se\*'curite\*' par l'obscurite\*', expression de\*'signant le fait de cacher vos bugs au lieu de les corriger, est vraiment une faible se\*'curite\*'. .PP Vous pouvez essayer d'utiliser le chiffrement via des filtres de sources (Filter::* sur \s-1CPAN\s0 ou Filter::Util::Call et Filter::Simple depuis Perl 5.8). Mais les craqueurs peuvent encore le de\*'chiffrer. Vous pouvez essayer d'utiliser le compilateur de byte code et l'interpre\*'teur de\*'crit ci\-dessous, mais les craqueurs peuvent encore le de\*'compiler. Vous pouvez essayer d'utiliser le compilateur de code natif de\*'crit ci\-dessous, mais les craqueurs peuvent encore le de\*'sassembler. Ces solutions posent des degre\*'s varie\*'s de difficulte\*' aux gens voulant obtenir votre code, mais aucune ne peut de\*'finitivement le dissimuler (ceci est vrai pour tous les langages, pas uniquement Perl). .PP Si vous e\*^tes inquiet que des gens profitent de votre code, alors le point crucial est que rien a\*` part une licence restrictive ne vous donnera de se\*'curite\*' le\*'gale. Licenciez votre logiciel et pimentez-le de phrases menac\*,antes comme \*(L"Ceci est un logiciel proprie\*'taire non publie\*' de la socie\*'te\*' \s-1XYZ\s0. L'acce\*`s qui vous y est donne\*' ne vous donne pas la permission de l'utiliser bla bla bla\*(R". Vous devriez voir un avocat pour e\*^tre sur que votre vocabulaire tiendra au tribunal. .Sh "Unicode" .IX Subsection "Unicode" Unicode est une technologie nouvelle et complexe qui peut facilement amener quelqu'un vers de nouvelles embu\*^ches lie\*'es a\*` la se\*'curite\*'. Voir perluniintro pour la pre\*'sentation ge\*'ne\*'rale, perlunicode pour les de\*'tails et en particulier perl. .Sh "Attaques par complexite\*' algorithmique" .IX Subsection "Attaques par complexite' algorithmique" Certains algorithmes internes utilise\*'s dans l'imple\*'mentation de Perl peuvent e\*^tre attaque\*'s en fournissant des entre\*'es choisies spe\*'cialement pour consommer soit beaucoup de temps, soit beaucoup de me\*'moire, soit les deux. C'est ce qu'on appelle des attaques par \fIDe\*'ni de service\fR (DoS \- Denial of Service). .IP "\(bu" 4 La fonction de hachage \- l'algorithme utilise\*' pour \*(L"ordonne\*'\*(R" les cle\*'s des tables de hachage a change\*' plusieurs fois au cours du de\*'veloppement de Perl, principalement pour des raisons d'efficacite\*'. En Perl 5.8.1, les aspects concernant la se\*'curite\*' ont aussi e\*'te\*' pris en compte. .Sp Dans les versions ante\*'rieures a\*` la 5.8.1, il e\*'tait relativement facile de ge\*'ne\*'rer des donne\*'es qui, en tant que cle\*'s de hachage, amenait Perl a\*` consommer e\*'norme\*'ment de temps a\*` cause d'une mauvaise gestion des structures internes de hachage. En Perl 5.8.1, la fonction de hachage est volontairement perturbe\*'e par un ge\*'ne\*'rateur pseudo\-ale\*'atoire afin de rendre tre\*`s difficile la ge\*'ne\*'ration de mauvaises cle\*'s de hachage. Voir \*(L"\s-1PERL_HASH_SEED\s0\*(R" in perlrun pour plus d'information. .Sp La perturbation ale\*'atoire est utilise\*'e par de\*'faut mais si quelqu'un souhaite simluer l'ancien comportement, il peut positionner la variable d'environnement \s-1PERL_HASH_SEED\s0 a\*` ze\*'ro (ou toute autre valeur entie\*`re). Une raison pour vouloir retrouver cet ancien comportement est qu'avec le nouveau comportement, deux exe\*'cutions successives de Perl ordonnent les cle\*'s de hachage diffe\*'remment ce qui peut perturber des applications (avec Data::Dumper, les sorties de deux exe\*'cutions sur les me\*^me donne\*'es ne sons pas identiques). .Sp \&\fBPerl n'a jamais garanti l'ordre des cle\*'s des tables de hachage\fR et cet ordre a de\*'ja\*` change\*' plusieurs fois depuis l'arrive\*'e de Perl 5. De plus, l'ordre des cle\*'s a toujours e\*'te\*' et continue d'e\*^tre modifie\*' par une insertion. .Sp Notez aussi que bien que cet ordre puisse e\*^tre conside\*'re\*' comme ale\*'atoire, il ne devrait pas \fBpas\fR e\*^tre utilise\*' pour du me\*'lange ale\*'atoire de liste (utilisez la fontion \fIList::Util::shuffle()\fR du module List::Util qui est un module standard depuis Perl 5.8.0 ou le module \s-1CPAN\s0 Algorithm::Numerical::Shuffle), pour ge\*'ne\*'rer des permutations (utilisez les modules \s-1CPAN\s0 Algorithm::Permute ou Algorithm::FastPermute) ou pour des applications de cryptographie. .IP "\(bu" 4 Les expressions rationnelles \- Le moteur d'expression rationnelle de Perl est aussi appele\*' \s-1NFA\s0 (Non\-Finite Automaton \- Automate non fini) ce qui signifie, entre autres, qu'il peut facilement consommer e\*'norme\*'ment de temps et d'espace me\*'moire si une expression rationnelle est reconnaissable de nombreuses manie\*`res diffe\*'rentes. Des expressions rationnelles correctement conc\*,ues peuvent empe\*^cher cela mais c'est loin d'e\*^tre facile (nous vous recommandons la lecture du livre \&\*(L"Mastering Regular Expressions\*(R", voir aussi perlfaq2). L'utilisation d'espace me\*'moire trop important se manifeste par un de\*'passement de capacite\*' de me\*'moire (out of memory) de Perl. .IP "\(bu" 4 Le tri \- l'algorithme de tri rapide (quicksort) utilise\*' dans les versions de Perl ante\*'rieures a\*` la version 5.8.0 pour imple\*'menter la fonction \fIsort()\fR est facilement pertubable pour l'amener a\*` consommer beaucoup de temps. Le simple tri d'une liste de\*'ja\*` trie\*'e suffit. Depuis la version 5.8.0 de Perl, un autre algorithme de tri est utilise\*'\ : le 'mergesort'. Ce nouvel algorithme est insensible a\*` ses donne\*'es d'entre\*'e. Il ne peut donc plus e\*^tre dupe\*'. .PP Pour plus d'information voir et n'importe quel livre d'informatique abordant la complexite\*' algorithmique. .SH "VOIR AUSSI" .IX Header "VOIR AUSSI" perlrun pour sa description du nettoyage des variables d'environnement. .SH "TRADUCTION" .IX Header "TRADUCTION" .Sh "Version" .IX Subsection "Version" Cette traduction franc\*,aise correspond a\*` la version anglaise distribue\*'e avec perl 5.8.8. Pour en savoir plus concernant ces traductions, consultez . .Sh "Traducteur" .IX Subsection "Traducteur" Tarduction initiale\ : Roland Trique <\fIroland.trique@free.fr\fR>. Mise a\*` jour\ : Paul Gaborit . .Sh "Relecture" .IX Subsection "Relecture" Re\*'gis Julie\*' <\fIregis.julie@cetelem.fr\fR>