• Aucun résultat trouvé

1. Le filtrage pour la sécurité, qui sera géré par des fonctions de validation ou de net- toyage systématique (comme filter_var) ou, dans le cas de la couche de persistance basée sur PDO, par la préparation systématique des requêtes.

2. Le filtrage pour la cohérence des données, qui nécessite généralement un connais- sance de la sémantique des objets métiers et de leurs attributs (Logique Métier), est se fonde le plus souvent sur des tests d’expressions régulières. Dans notre implémentation, ce filtrage sera réalisé dans une classe de validation et de fabrique d’instances des classes de représentation des données métier.

5.2.1 Prévention des injections HTML

Nous proposons ici un utilitaire un peu général qui définit des politiques de filtrage pour éviter les injections HTML. Différentes politiques sont prévues :

1. Aucun filtrage ;

2. Élimination des balises (voir filter_var) par un filtre FILTER_SANITIZE_STRING (avec ou sans échappement des simples ou doubles quotes) ;

3. Échappement systématique (voir htmlentities) de toutes les entités HTML (y compris les caractères accentués et autres caractères plus ou moins inoffensifs) ;

4. Échappement uniquement des caractères spéciaux HTML (voir htmlspecialchars). Deux méthodes permettent respectivement de filtrer la chaîne et d’inverser l’échappement pour restaurer la chaîne (dans la mesure où les caractères n’auraient pas été éliminés par un filtre de nettoyage (de type SANITIZE). Le but de l’inversion de l’échappement est de permettre, si besoin, de rétablir la chaîne d’origine, par exemple pour que l’utilisateur puisse la modifier dans un formulaire.

Code Source 5.2 : /forms2/classes/ValidationUtils.php

1 < ?php

2 namespace CoursPHP\ C o n t r o l e u r ;

3 /* * @ b r i e f Permet l a v a l i d a t i o n d e s donn é e s pour é v i t e r l e s i n j e c t i o n s HTML 4 * Typiquement , l e s donn é e s r e ç ues v i a $_REQUEST s o n t f i l t r é e s a v a n t d ’ ê t r e 5 * a f f i c h é e s dans une page ou re−soumises dans un f o r m u l a i r e .

6 * P l u s i e u r s p o l i t i q u e s de f i l t r a g e ( n e t t o y a g e ou é chappement ) s o n t pr é v u e s . */ 7 c l a s s V a l i d a t i o n U t i l s { 8 // P o l i t i q u e s de n e t t o y a g e e t d ’ é chappement : 9 10 /* * 1) Ne r i e n f i l t r e r n i c h a n g e r */ 11 c o n s t SANITIZE_POLICY_NONE = 0 ;

12 /* * 2) Supprimer l e s b a l i s e s HTML uniquement , mais ne pas é c h a p p e r . 13 * L a i s s e r l e s q u o t e s ” e t a p o s t r o p h e s ’ i n c h a n g é e s */ 14 c o n s t SANITIZE_POLICY_DISCARD_HTML_NOQUOTE = 1 ; 15 /* * 3) Supprimer l e s b a l i s e s HTML e t é c h a p p e r l e s q u o t e s ” e t ’ . 16 * L a i s s e r l e s q u o t e s e t a p o s t r o p h e s i n c h a n g é e s */ 17 c o n s t SANITIZE_POLICY_DISCARD_HTML = 2 ; 18 /* * 4) Éc h a p p e r t o u t e s l e s c a r a c t è r e s sp é c i a u x HTML ( < , >, ” , e t c . ) */ 19 c o n s t SANITIZE_POLICY_ESCAPE_SPECIAL_CHARS = 3 ; 20 /* * 5) Éc h a p p e r t o u t e s l e s e n t i t é s HTML ( y compris l e s a c c e n t s , e t c . ) */ 21 c o n s t SANITIZE_POLICY_ESCAPE_ENTITIES = 4 ;

22

23 /* * @ b r i e f Mé t h o d e de N e t t o y a g e e t /ou d ’ é chappement

24 * @param $ c h a i n e { inOut } l a cha î ne de c a r a c t è r e s à f i l t r e r

25 * @param $ p o l i c y l a p o l i t i q u e de f i l t r a g e ( v o i r c o n s t a n t e s de c l a s se ) 26 * @return f a l s e en c a s d ’ é c h e c ( $ c h a i n e n ’ e s t pas une cha î ne ) */ 27 private s t a t i c function f i l t e r M e t h o d (& $ c h a i n e , $ p o l i c y ) {

28 // S i l a c h a i n e n ’ e s t pas d é f i n i e , on met une cha î ne v i d e 29 $ c h a i n e = i s s e t ( $ c h a i n e ) ? $ c h a i n e : ” ” ;

30 switch ( $ p o l i c y ) {

31 case s e l f : :SANITIZE_POLICY_DISCARD_HTML_NOQUOTE :

32 // Supprimer l e s b a l i s e s uniquement , mais ne pas é c h a p p e r 33 $ c h a i n e = f i l t e r _ v a r ( $ c h a i n e , FILTER_SANITIZE_STRING, 34 FILTER_FLAG_NO_ENCODE_QUOTES) ; 35 break ; 36 case s e l f : :SANITIZE_POLICY_DISCARD_HTML : 37 // Supprimer l e s b a l i s e s e t é c h a p p e r l e s q u o t e s ” e t ’ . 38 $ c h a i n e = f i l t e r _ v a r ( $ c h a i n e , FILTER_SANITIZE_STRING, ENT_QUOTES) ; 39 break ; 40 case s e l f : :SANITIZE_POLICY_ESCAPE_SPECIAL_CHARS : 41 // Éc h a p p e r t o u t e s l e s c a r a c t è r e s sp é c i a u x HTML ( < , >, ” , e t c . ) 42 $ c h a i n e = htmlspecialchars ( $ c h a i n e , ENT_QUOTES, ’UTF−8 ’ ) ;

43 break ;

44 case s e l f : :SANITIZE_POLICY_ESCAPE_ENTITIES :

45 // Éc h a p p e r t o u t e s l e s e n t i t é s HTML ( y compris l e s a c c e n t s , e t c . ) 46 $ c h a i n e = htmlentities ( $ c h a i n e , ENT_QUOTES, ’UTF−8 ’ ) ;

47 break ; 48 default : // SANITIZE_POLICY_NONE : r i e n à f a i r e 49 } 50 return $ c h a i n e === f a l s e ? f a l s e : true ; 51 } 52 53 /* * @ b r i e f Mé t h o d e d ’ I n v e r s i o n d ’ é chappement

54 * @param $ c h a i n e l a cha î ne de c a r a c t è r e s à r e s t a u r e r s u i t e à un é chappement 55 * @param $ p o l i c y l a p o l i t i q u e de f i l t r a g e ( v o i r c o n s t a n t e s de c l a s se ) */ 56 private s t a t i c function f i l t e r M e t h o d R e v e r s e (& $ c h a i n e , $ p o l i c y ) {

57 // S i l a c h a i n e n ’ e s t pas d é f i n i e , on met une cha î ne v i d e 58 $ c h a i n e = i s s e t ( $ c h a i n e ) ? $ c h a i n e : ” ” ; 59 switch ( $ p o l i c y ) { 60 case s e l f : :SANITIZE_POLICY_DISCARD_HTML : 61 // On r e s t a u r e j u s t e s l e s s i m p l e s e t d o u b l e s q u o t e s q u i s o n t html−encod é e s 62 $tmp = preg_replace ( ’ /^\& q u o t \ ; $/ ’ , ” \” ” , i s s e t ( $ c h a i n e ) ? $ c h a i n e : ” ” ) ; 63 $ c h a i n e = preg_replace ( ’ /^\&39\ ; $/ ’ , ” ’ ” , $tmp ) ; 64 break ; 65 case s e l f : :SANITIZE_POLICY_ESCAPE_SPECIAL_CHARS : 66 // On i n v e r s e l ’ encodage d e s c a r a c t è r e s sp é c i a u x HTML 67 $ c h a i n e = h t m l s p e c i a l c h a r s _ d e c o d e ( $ c h a i n e , ENT_QUOTES, ’UTF−8 ’ ) ; 68 break ; 69 case s e l f : :SANITIZE_POLICY_ESCAPE_ENTITIES : 70 // On i n v e r s e l ’ encodage d e s e n t i t é s HTML 71 $ c h a i n e = h t m l e n t i t i e s _ d e c o d e ( $ c h a i n e , ENT_QUOTES, ’UTF−8 ’ ) ; 72 break ;

73 default : // SANITIZE_POLICY_DISCARD_HTML_NOQUOTE : Rien à r e s t a u r e r

74 // SANITIZE_POLICY_NONE : r i e n à f a i r e

76 } 77

78 /* * @ b r i e f Mé t h o d e de ( N e t t o y a g e e t /ou d ’ é chappement )

79 * e t /ou d ’ i n v e r s i o n d ’ é chappement

80 * @param $ c h a i n e l a cha î ne de c a r a c t è r e s à f i l t r e r

81 * @param $ r e v e r s e d t r u e s ’ i l f a u t a p p l i q u e r une i n v e r s i o n d ’ é chappement 82 * f a l s e s ’ i l f a u t a p p l i q u e r un n e t t o y a g e e t /ou é chappement 83 * @param $ p o l i c y l a p o l i t i q u e de f i l t r a g e ( v o i r c o n s t a n t e s de c l a s se ) * */ 84 public s t a t i c function f i l t e r S t r i n g (& $ c h a i n e , $ r e v e r s e d , $ p o l i c y ) {

85 i f ( ! i s s e t ( $ p o l i c y ) ) {

86 throw new \ E x c e p t i o n ( ” P o l i t i q u e de f i l t r a g e non d é f i n i e ” ) ;

87 } 88 return $ r e v e r s e d ? s e l f : : f i l t e r M e t h o d R e v e r s e ( $ c h a i n e , $ p o l i c y ) : 89 s e l f : : f i l t e r M e t h o d ( $ c h a i n e , $ p o l i c y ) ; 90 } 91 } 92 ?>

La classe AdresseValidation permet, en utilisant une politique de filtrage de la classe ValidationUtils, de fitrer les attributs d’une adresse.

Les isntances d’Adresse suivent le modèle POPO. Une méthode prend en argument une instance d’Adresse, et une autre méthode prend en argument un tableau associatif dont les clefs correspondent aux noms d’attributs d’Adresse (typiquement, $inputArray sera le tableau $_POST ou $_REQUEST pour créer une instance à partir des données saisies dans un formulaire.

Code Source 5.3 : /forms2/classes/AdresseValidation.php

1 < ?php

2 namespace CoursPHP\ M e t i e r ;

3 use \CoursPHP\ C o n t r o l e u r \ V a l i d a t i o n U t i l s a s V a l i d a t i o n U t i l s ; // Ra c c o u r c i c l a s se 4

5 /* * @ b r i e f Permet l a v a l i d a t i o n i n i t i a l e d e s donn é e s d ’ une a d r e s s e .

6 * Typiquement , l e s donn é e s q u i v i e n n e n t du c l i e n t r e ç ues ( v i a $_REQUEST . . . ) 7 * N e t t o y a g e de t o u t e s l e s cha î nes . I n i t i a l i s a t i o n d e s i n p u t s i n e x i s t a n t s */ 8 c l a s s A d r e s s e V a l i d a t i o n {

9 /* * @ b r i e f V a l i d a t i o n e t i n i t i a l i s a t i o n d e s donn é e s d ’ une i n s t a n c e Adresse 10 * à p a r t i r d ’ une i n s t a n c e de POPO Adresse

11 * @param $ a d r e s s e i n s t a n c e d ’ Adresse

12 * @param $ r e v e r s e d t r u e pour a p p l i q u e r l a mé t h o d e d ’ i n v e r s i o n d ’ é chappement 13 * f a l s e pour l a mé t h o d e de n e t t o y a g e e t /ou d ’ é chappement 14 * @param $ p o l i c y l ’ une d e s p o l i t i q u e s d é f i n i e s par V a l i d a t i o n U t i l s * */ 15 public s t a t i c function f i l t e r A d r e s s e ( $ a d r e s s e , $ r e v e r s e d , $ p o l i c y ) { 16 V a l i d a t i o n U t i l s : : f i l t e r S t r i n g ( $ a d r e s s e−>idAdresse , $reversed , $ p o l i c y ) ; 17 V a l i d a t i o n U t i l s : : f i l t e r S t r i n g ( $ a d r e s s e−>idPersonne , $reversed , $ p o l i c y ) ; 18 V a l i d a t i o n U t i l s : : f i l t e r S t r i n g ( $ a d r e s s e−>numeroRue , $reversed , $ p o l i c y ) ; 19 V a l i d a t i o n U t i l s : : f i l t e r S t r i n g ( $ a d r e s s e−>rue , $reversed , $ p o l i c y ) ; 20 V a l i d a t i o n U t i l s : : f i l t e r S t r i n g ( $ a d r e s s e−>complementAddr , $reversed , $ p o l i c y ) ; 21 V a l i d a t i o n U t i l s : : f i l t e r S t r i n g ( $ a d r e s s e−>codePostal , $reversed , $ p o l i c y ) ; 22 V a l i d a t i o n U t i l s : : f i l t e r S t r i n g ( $ a d r e s s e−>v i l l e , $reversed , $ p o l i c y ) ; 23 V a l i d a t i o n U t i l s : : f i l t e r S t r i n g ( $ a d r e s s e−>pays , $reversed , $ p o l i c y ) ; 24 } 25 26 /* * @ b r i e f V a l i d a t i o n e t i n i t i a l i s a t i o n d e s donn é e s d ’ une a d r e s s e 27 * à p a r t i r d e s donn é e s r e ç ues dans l e s t a b l e a u a s s o c i a t i f

28 * ( t y p i q u e m e n t $_REQUEST ou $_POST) .

30 * d e s a t t r i b u t s d ’ Adresse

31 * @param $ a d r e s s e { inOut } I n s t a n c e d ’ Adresse à c r é e r ou i n i t i a l i s e r 32 * @param $ p o l i c y l ’ une d e s p o l i t i q u e s d é f i n i e s par V a l i d a t i o n U t i l s * */ 33 public s t a t i c function v a l i d a t i o n I n p u t ( $inputArray , &$ a d r e s s e , $ p o l i c y ) {

34 // S i $ a d r e s s e n ’ e s t pas une i n s t a n c e d ’ Adresse , on c r é e une i n s t a n c e : 35 i f ( ! is_object ( $ a d r e s s e ) | | !preg_match( ”/ Adresse$ / ” , get_ c l a s s ( $ a d r e s s e ) ) ) { 36 $ a d r e s s e = \CoursPHP\ M e t i e r \ A d r e s s e

37 : : g e t D e f a u l t I n s t a n c e ( $ i n pu t Ar r a y [ ’ i d P e r s o n n e ’ ] ,

38 $ i n p u t A r r ay [ ’ i d A d r e s s e ’ ] ) ;

39 }

40 // I n i t i a l i s a t i o n d e s a t t r i b u t s

41 $ a d r e s s e−>idAdresse = $inputArray [ ’ idAdresse ’ ] ;

42 $ a d r e s s e−>idPersonne = $inputArray [ ’ idPersonne ’ ] ;

43 $ a d r e s s e−>numeroRue =$inputArray [ ’ numeroRue ’ ] ; 44 $ a d r e s s e−>rue = $inputArray [ ’ rue ’ ] ;

45 $ a d r e s s e−>complementAddr = $inputArray [ ’ complementAddr ’ ] ;

46 $ a d r e s s e−>codePostal = $inputArray [ ’ codePostal ’ ] ;

47 $ a d r e s s e−>v i l l e = $inputArray [ ’ v i l l e ’ ] ;

48 $ a d r e s s e−>pays = $inputArray [ ’ pays ’ ] ;

49 // F i l t r a g e d e s a t t r i b u t s a v e c l a p o l i t i q u e 50 s e l f : : f i l t e r A d r e s s e ( $ a d r e s s e , f a l s e , $ p o l i c y ) ;

51 }

52 } 53 ?>

La classe AdresseView permet de générer le code HTML d’une instance d’Adresse, en appli- quant une politique de filtrage (par défaut htmlentities) avant de générer le code HTML. La chaîne retournée peut alors être affichée (pour la politique par défaut) sans risque d’injection

HTML.

Code Source 5.4 : /forms2/classes/AdresseView.php

1 < ?php

2 namespace CoursPHP\Vue ;

3 /* * @ b r i e f Impl é mente l a g éné r a t i o n d ’HTML pour a f f i c h e r une Adresse dans une vue

4 * dans un n a v i g a r e u r .

5 * Impl é mente a u s s i d e s u t i l i t a i r e s de c o n v e r s i o n à p a r t i r d ’ une Adresse 6 * pour o b t e n i r f a c i l e m e n t l e code HTML pour a f f i c h e r une Adresse . */ 7 c l a s s AdresseView {

8 /* * @ b r i e f Mé t h o d e de g éné r a t i o n de code HTML. Permet d ’ a f f i c h e r une a d r e s s e . 9 * Les a t t r i b u t s s o n t é chapp é s pour é v i t e r t o u t r i s q u e d ’ i n j e c t i o n HTML 10 * @param $ a d r e s s e l ’ i n s t a n c e d ’ a d r e s s e à a f f i c h e r

11 * @param $ s a n i t i z e P o l i c y P o l i t i q u e pour e n c o d e r ou é c h a p p e r l e s a t t r i b u t s

12 * ( Voir l a c l a s se V a l i d a t i o n U t i l s )

13 * @return l e code HTML pour un a f f i c h a g e d é v e l o p p é . */ 14 public s t a t i c function getHtmlDevelopped ( $ a d r e s s e ,

15 $ s a n i t i z e P o l i c y = \CoursPHP\ C o n t r o l e u r \ V a l i d a t i o n U t i l s 16 : :SANITIZE_POLICY_ESCAPE_ENTITIES) { 17 i f ( \ CoursPHP\ M e t i e r \ A d r e s s e V a l i d a t i o n : : f i l t e r A d r e s s e ( 18 $ a d r e s s e , f a l s e , $ s a n i t i z e P o l i c y ) === f a l s e ) { 19 return ” Adresse i n c o r r e c t e ” ; 20 } 21 $htmlCode = ”<s t r o n g >Adresse : </s t r o n g ><b r />\n” ; 22 $htmlCode .= $ a d r e s s e−>numeroRue ; 23 i f ( !empty( $ a d r e s s e−>numeroRue ) ) 24 $htmlCode .= ” , ” ;

25 $htmlCode .= $ a d r e s s e−>rue ; 26 i f ( !empty( $ a d r e s s e−>rue ) ) 27 $htmlCode .= ”<b r/>” ; 28 $htmlCode .= $ a d r e s s e−>complementAddr ; 29 i f ( !empty( $ a d r e s s e−>complementAddr ) ) 30 $htmlCode .= ”<b r/>” ; 31 $htmlCode .= $ a d r e s s e−>codePostal . ” ” ; 32 $htmlCode .= $ a d r e s s e−>v i l l e ;

33 i f ( !empty( $ a d r e s s e−>v i l l e ) && !empty( $adresse −>pays ) )

34 $htmlCode .= ”<b r/>” ; 35 $htmlCode .= $ a d r e s s e−>pays . ”<br/>” ; 36 37 return $htmlCode ; 38 } 39 40 /* * @ b r i e f Mé t h o d e de g éné r a t i o n d ’HTML. Permet d ’ a f f i c h e r une a d r e s s e . 41 * Les a t t r i b u t s s o n t é chapp é s pour é v i t e r t o u t r i s q u e d ’ i n j e c t i o n HTML 42 * @param $ a d r e s s e l ’ i n s t a n c e d ’ a d r e s s e à a f f i c h e r

43 * @param $ s a n i t i z e P o l i c y p o l i t i q u e de n e t t o y a g e / é chappement d e s a t t r i b u t s 44 * @return l e code HTML pour un a f f i c h a g e compact . */

45 public s t a t i c function getHtmlCompact ( $ a d r e s s e ,

46 $ s a n i t i z e P o l i c y = \CoursPHP\ C o n t r o l e u r \ V a l i d a t i o n U t i l s 47 : :SANITIZE_POLICY_ESCAPE_ENTITIES) { 48 i f ( \ CoursPHP\ M e t i e r \ A d r e s s e V a l i d a t i o n : : f i l t e r A d r e s s e ( 49 $ a d r e s s e , f a l s e , $ s a n i t i z e P o l i c y ) === f a l s e ) { 50 return ” Adresse i n c o r r e c t e ” ; 51 } 52 $htmlCode = ” ” ; 53 $htmlCode .= $ a d r e s s e−>numeroRue ; 54 i f ( !empty( $ a d r e s s e−>numeroRue ) ) 55 $htmlCode .= ” , ” ; 56 $htmlCode .= $ a d r e s s e−>rue ; 57 i f ( !empty( $ a d r e s s e−>rue ) ) 58 $htmlCode .= ” , ” ; 59 $htmlCode .= $ a d r e s s e−>complementAddr ; 60 i f ( !empty( $ a d r e s s e−>complementAddr ) ) 61 $htmlCode .= ” , ” ; 62 $htmlCode .= $ a d r e s s e−>codePostal . ” ” ; 63 $htmlCode .= $ a d r e s s e−>v i l l e ;

64 i f ( !empty( $ a d r e s s e−>v i l l e ) && !empty( $adresse −>pays ) )

65 $htmlCode .= ” , ” ; 66 $htmlCode .= $ a d r e s s e−>pays ; 67 68 return $htmlCode ; 69 } 70 } // end o f c l a s s AdresseView 71 ?>

Voici un fichier de test, qui affiche une instance d’adresse en utilisant différentes politiques de filtrage. Le code HTML d’affichage de l’instance, qui apparaît ci-dessous, illustre les différentes politiques de filtrage/nettoyage.

Code Source 5.5 : /forms2/testFiltrageHTML.php (cf. Fig 5.1)

1 < ?php

2 r e q u i r e _ o n c e ( dirname (__FILE__) . ’ / c l a s s e s / VueHtmlUtils . php ’ ) ; 3 r e q u i r e _ o n c e ( dirname (__FILE__) . ’ / c l a s s e s / Adresse . php ’ ) ;

Figure 5.1 : Illustration du code source 5.5

4 r e q u i r e _ o n c e ( dirname (__FILE__) . ’ / c l a s s e s / A d r e s s e V a l i d a t i o n . php ’ ) ; 5 r e q u i r e _ o n c e ( dirname (__FILE__) . ’ / c l a s s e s / V a l i d a t i o n U t i l s . php ’ ) ; 6 r e q u i r e _ o n c e ( dirname (__FILE__) . ’ / c l a s s e s / AdresseView . php ’ ) ;

7 // Header HTML5

8 echo CoursPHP\Vue\ VueHtmlUtils : :enTeteHTML5 ( ’ F i l t r a g e d \ ’ une Adresse ’ ,

9 ’UTF−8 ’ , ’ myStyle . c ss ’ ) ;

10 echo ”<h1>F i l t r a g e , n e t t o y a g e e t é chappement d ’ une Adresse </h1>” ;

11 // Cré a t i o n d ’ une i n s t a n c e v i a l e c o n s t r u c t e u r de POPO 12 $ a d r e s s e = new CoursPHP\ M e t i e r \ A d r e s s e (

13 ” 54522 f 6 a b 1 ” , ”9 c 9 e f c d a 3 2 ” , ”2 b i s ” ,

14 ”Rue de l ’ a v e n i r < Companie” , // a v e c un c a r a c t è r e ’ < ’ ! ! ! 15 ”Ré s i d . \” Les F l o t s B l e u s \” ” , ” 63000 ” , ” Clermont−Ferrand ” , ”” ) ;

16

17 // P o l i t i q u e par d é f a u t : h t m l e n t i t i e s

18 // ( on c l o n e pour pr é s e r v e r l ’ a d r e s s e d ’ o r i g i n e ) 19 echo ”<p>ESCAPE ENTITIES : <b r />\n<s t r o n g > ”

20 . CoursPHP\Vue\ AdresseView : :getHtmlCompact ( $ a d r e s s e−>clone ( ) )

21 . ” \n</s t r o n g ></p>\n” ;

22 // P o l i t i q u e s p e c i a l chars , NO_ENCODE_QUOTES ( on c l o n e . . . )

23 echo ”<p>ESCAPE SPECIAL CHARS, NO_ENCODE_QUOTES : <b r />\n<s t r o n g > ”

24 . CoursPHP\Vue\ AdresseView : :getHtmlCompact ( $ a d r e s s e−>clone ( ) ,

25 \CoursPHP\ C o n t r o l e u r \ V a l i d a t i o n U t i l s

26 : :SANITIZE_POLICY_ESCAPE_SPECIAL_CHARS)

27 . ” \n</s t r o n g ></p>\n” ;

28 // P o l i t i q u e s p e c i a l chars , NO_ENCODE_QUOTES ( on c l o n e . . . )

29 echo ”<p>DISCARD SPECIAL CHARS, NO_ENCODE_QUOTES : <b r />\n<s t r o n g > ”

30 . CoursPHP\Vue\ AdresseView : :getHtmlCompact ( $ a d r e s s e−>clone ( ) ,

31 \CoursPHP\ C o n t r o l e u r \ V a l i d a t i o n U t i l s

32 : :SANITIZE_POLICY_DISCARD_HTML_NOQUOTE)

33 . ” \n</s t r o n g ></p>\n” ;

34 // P o l i t i q u e s p e c i a l chars , ENCODE_QUOTES ( on c l o n e . . . )

35 echo ”<p>DISCARD SPECIAL CHARS, ENCODE_QUOTES : <b r />\n<s t r o n g > ”

36 . CoursPHP\Vue\ AdresseView : :getHtmlCompact ( $ a d r e s s e−>clone ( ) ,

37 \CoursPHP\ C o n t r o l e u r \ V a l i d a t i o n U t i l s

38 : :SANITIZE_POLICY_DISCARD_HTML)

39 . ” \n</s t r o n g ></p>\n” ; 40 // P o l i t i q u e ” ne r i e n f a i r e ”

41 echo ”<p>NE RIEN FAIRE : <b r />\n<s t r o n g > ”

42 . CoursPHP\Vue\ AdresseView : :getHtmlCompact ( $ a d r e s s e ,

43 \CoursPHP\ C o n t r o l e u r \ V a l i d a t i o n U t i l s

44 : :SANITIZE_POLICY_NONE)

45 . ” \n</s t r o n g ></p>” ;

46 echo CoursPHP\Vue\ VueHtmlUtils : :finFichierHTML5 ( ) ;

47 ?>

Voici la partie de la sortie standard (code HTML) du CGI qui montre le résultat des différentes formes de filtrage et d’échappement :

Sortie HTML du CGI

1 <p>ESCAPE ENTITIES : <br />

2 <s trong> 2 b i s , Rue de l &#039 ; a v e n i r &l t ; Companie ,

3 R&e a c u t e ; s i d . &quot ; Les F l o t s B l e u s&quot ; , 63000 Clermont−Ferrand 4 </s trong></p>

5 <p>ESCAPE SPECIAL CHARS, NO_ENCODE_QUOTES : <br /> 6 <s trong> 2 b i s , Rue de l &#039 ; a v e n i r &l t ; Companie ,

7 Ré s i d . &quot ; Les F l o t s B l e u s&quot ; , 63000 Clermont−Ferrand

8 </s trong></p>

9 <p>DISCARD SPECIAL CHARS, NO_ENCODE_QUOTES : <br /> 10 <s trong> 2 b i s , Rue de l ’ a v e n i r ,

11 Ré s i d . ” Les F l o t s B l e u s ” , 63000 Clermont−Ferrand

12 </s trong></p>

13 <p>DISCARD SPECIAL CHARS, ENCODE_QUOTES : <br /> 14 <s trong> 2 b i s , Rue de l &#39 ; a v e n i r ,

15 Ré s i d . &#34 ;Les F l o t s B l e u s &#34 ;, 63000 Clermont−Ferrand

16 </s trong></p>

17 <p>NE RIEN FAIRE : <br />

18 <s trong> 2 b i s , Rue de l ’ a v e n i r < Companie ,

19 Ré s i d . ” Les F l o t s B l e u s ” , 63000 Clermont−Ferrand 20 </s trong></p>

5.2.2 Garantie de la Logique Métier

Nous proposons tout d’abord des méthodes génériques de test d’expressions régulières pour les langues d’Europe occidentale (jeu de caractères Latin-1 tel que défini par la norme ISO 8859-1), ce qui inclut la langue française, avec ou sans chiffres. Notons que le jeu de caractères que nous utilisons pour l’encodage des caractères est toujours le standard UTF-8. Le je de caractères

Latin-1 est juste utilisé dans les expressions régulières.

Code Source 5.7 : /forms2/classes/ExpressionsRegexUtils.php

1 < ?php 2 namespace CoursPHP\ M e t i e r ; 3 /* * @ b r i e f C l a s s e de d é f i n i t i o n s d ’ E x p r e s s i o n s Ré g u l i è r e s d ’ u s a g e g éné r a l . 4 * Dé f i n i t q u e l q u e s e x p r e s s i o n s r é g u l i è r e s u t i l e s pour l a l a n g u e l o c a l e s u p p o r t é e 5 * e t l e s r o u t i n e s de t e s t s u r une cha î ne c o r r e s p o n d a n t . */ 6 c l a s s E x p r e s s i o n s R e g e x U t i l s { 7 /* * @ b r i e f : e x p r e s s i o n r é g u l i è r e pour l a l a n g u e Fran ç a i s e a v e c a c c e n t s */ 8 private s t a t i c function g e t R e g e x L a t i n 1 ( ) { 9 return ’ / ^ [ a−zA−ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæç è é êö ì í î ïðñòó ôõö÷øùú ûĀāüýþÿ \”\ ’\−\ ]* $/ ’ ;

10 } 11

12 /* * @ b r i e f : e x p r e s s i o n r é g u l i è r e pour l a l a n g u e Fran ç a i s e a v e c a c c e n t s , 13 * e t c h i f f r e s */

14 private s t a t i c function getRegexLatin1WithNumbers ( ) {

15 return ’ /^[0−9a−zA−ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæç è é êö ì í î ïðñòó ô õö÷øùúûĀāüýþÿ \”\ ’\−\ ]* $/ ’ ; 16 } 17 18 /* * @ b r i e f : e x p r e s s i o n r é g u l i è r e pour l a l a n g u e Fran ç a i s e a v e c a c c e n t s , 19 * c h i f f r e s e t p o n c t u a t i o n */

20 private s t a t i c function getRegexLatin1WithNumbersAndPunctuation ( ) {

21 return ’ /^[\ !\.\ :\ ;\ ?\ ,0−9a−zA−ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæç è é êö

ì í î ïðñòó ôõö÷øùúûĀāüýþÿ \”\ ’\−\ ]* $/ ’ ;

22 }

23

24 /* * @ b r i e f : Test e x p r e s s i o n r é g u l i è r e pour l a l a n g u e Fran ç a i s e a v e c a c c e n t s 25 * a v e c c o n d i t i o n s de l o n g u e u r ( par exemple pour un champ o b l i g a t o i r e ) */ 26 public s t a t i c function i s V a l i d L a t i n 1 ( $ c h a i n e , $minLength , $maxLength ) {

27 return ( i s s e t ( $ c h a i n e ) &&

28 s t r l e n ( $ c h a i n e ) >= $minLength && s t r l e n ( $ c h a i n e ) <= $maxLength

29 && preg_match( s e l f : :g e t R e g e x L a t i n 1 ( ) , $ c h a i n e ) ) ;

30 }

31

32 /* * @ b r i e f : Test e x p r e s s i o n r é g u l i è r e pour l a l a n g u e Fran ç a i s e a v e c a c c e n t s 33 * e t c h i f f r e s , a v e c c o n d i t i o n s de l o n g u e u r

34 * ( par exemple pour un champ o b l i g a t o i r e ) */

35 public s t a t i c function isValidLatin1WithNumbers ( $ c h a i n e ,

36 $minLength , $maxLength ) {

37 return ( i s s e t ( $ c h a i n e ) &&

38 s t r l e n ( $ c h a i n e ) >= $minLength && s t r l e n ( $ c h a i n e ) <= $maxLength

39 && preg_match( s e l f : :getRegexLatin1WithNumbers ( ) , $ c h a i n e ) ) ;

40 }

41

42 /* * @ b r i e f : Test e x p r e s s i o n r é g u l i è r e pour l a l a n g u e Fran ç a i s e a v e c a c c e n t s , 43 * c h i f f r e s e t p o n c t u a t i o n , a v e c c o n d i t i o n s de l o n g u e u r

44 * ( par exemple pour un champ o b l i g a t o i r e ) */

45 public s t a t i c function isValidLatin1WithNumbersAndPunctuation ( $ c h a i n e ,

46 $minLength , $maxLength ) {

47 return ( i s s e t ( $ c h a i n e ) &&

48 s t r l e n ( $ c h a i n e ) >= $minLength && s t r l e n ( $ c h a i n e ) <= $maxLength

49 && preg_match( s e l f : :getRegexLatin1WithNumbersAndPunctuation ( ) , $ c h a i n e ) ) ;

50 }

51

52 /* * @ b r i e f : Test e x p r e s s i o n r é g u l i è r e p a s s é e en paramètre

53 * a v e c c o n d i t i o n s de l o n g u e u r ( par exemple pour un champ o b l i g a t o i r e ) */ 54 public s t a t i c function i s V a l i d S t r i n g ( $ c h a i n e , $regExp , $minLength , $maxLength )

{

55 return ( i s s e t ( $ c h a i n e ) &&

56 s t r l e n ( $ c h a i n e ) >= $minLength && s t r l e n ( $ c h a i n e ) <= $maxLength

57 && preg_match( $regExp , $ c h a i n e ) ) ;

58 }

59 } 60 ?>

5.2.3 Fabrique d’Adresse

Nous présentons aussi une fabrique d’adresses qui construit des instances à partir de données issues d’un formulaire, tout en construisant un tableau d’erreurs en cas d’exception générée au niveau des setters. Le tableau d’erreurs $dataErrors, passé par références, contiendra des couples clé/valeur, dont la clé sera le nom de l’attribut de la classe Adresse et la valeur sera le messages de l’exception générée dans le setter de cet attribut. Si aucune exception n’est générée dans les setter, le tableau d’erreurs est vide.

Code Source 5.8 : /forms2/classes/AdresseFabrique.php

1 < ?php

2 namespace CoursPHP\ M e t i e r ;

3 /* * @ b r i e f Impl é mente l a c o n s t r u c t i o n d ’ une i n s t a n c e d ’ Adresse v a l i d é e 4 * à p a r t i r d e s donn é es , par exemple s a i s i e s dans un f o r m u l a i r e . 5 * Les e r r e u r s g éné r é e s dans l e s v a l i d a t e u r s d e s a t t r i b u t s ,

6 * q u i r e f l è t e n t l a l o g i q u e mé t i e r , q u i s o n t r e ç ues v i a d e s e x c e p t i o n s , 7 * s o n t accumul é e s dans un t a b l e a u a s s o c i a t i f d ’ e r r e u r s ,

8 * pour g éné r e r l e c a s é ch é ant une vue d ’ e r r e u r . */ 9 c l a s s A d r e s s e F a b r i q u e {

10 /* * @ b r i e f permet de v a l i d e r l ’ ID u n i q u e .

11 * @param $ i d A d r e s s e { inOut } i d e n t i f i a n t u n i q u e à v a l i d e r / r é i n i t i a l i s e r 12 * @param $ d a t a E r r o r s { inOut } t a b e a u a s s o c i a t i f de remont é e d ’ e r r e u r s . */ 13 protected s t a t i c function v a l i d a t e I d A d r e s s e (& $ i d A d r e s s e , &$ d a t a E r r o r s ) {

14 i f ( ! i s s e t ( $ i d A d r e s s e ) | | !preg_match( ” /^[0−9a−f ]{10} $/” , $idAdresse ) ) {

15 $ d a t a E r r o r s [ ’ i d A d r e s s e ’ ] = ” Erreur , i d e n t i f i a n t d ’ Adresse \” ” 16 . $ i d A d r e s s e . ” \” i n c o r r e c t ” ; 17 $ i d A d r e s s e = ” ” ; 18 } 19 } 20 21 /* * @ b r i e f permet de v a l i d e r l ’ ID u n i q u e de l ’ a g r é g a t Personne . 22 * @param $ i d P e r s o n n e { inOut } i d e n t i f i a n t u n i q u e à v a l i d e r / r é i n i t i a l i s e r 23 * @param $ d a t a E r r o r s { inOut } t a b e a u a s s o c i a t i f de remont é e d ’ e r r e u r s . */ 24 protected s t a t i c function v a l i d a t e I d P e r s o n n e (& $i d P e r s on ne , &$ d a t a E r r o r s ) {

25 i f ( ! i s s e t ( $ i d P e r s o n n e ) | | !preg_match( ” /^[0−9a−f ]{10} $/” , $idPersonne ) ) {

26 $ d a t a E r r o r s [ ’ i d P e r s o n n e ’ ] = ” Erreur , i d e n t i f i a n t de Personne \” ” 27 . $ i d P e r s o n n e . ” \” i n c o r r e c t ” ; 28 $ i d P e r s o n n e = ” ” ; 29 } 30 } 31

32 /* * @ b r i e f permet de v a l i d e r l e numé ro dans l a rue / p l a c e .

33 * @param $numeroRue { inOut } numé ro à v a l i d e r e t /ou r é i n i t i a l i s e r

34 * @param $ d a t a E r r o r s { inOut } t a b e a u a s s o c i a t i f de remont é e d ’ e r r e u r s . */ 35 protected s t a t i c function validateNumeroRue(&$numeroRue , &$ d a t a E r r o r s ) {

36 i f ( ! E x p r e s s i o n s R e g e x U t i l s : :isValidLatin1WithNumbers ( $numeroRue , 0 , 5 0 ) ) {

37 $ d a t a E r r o r s [ ’ numeroRue ’ ] = ” Erreur , l e numé ro de l a rue \” ” . $numeroRue . ” \”

38 . ” d e v r a i t comporter au p l u s 50 c a r a c t è r e s ” 39 . ” ( a l p h a b é t i q u e s , c h i f f r e s s a n s p o n c t u a t i o n ) ” ; 40 $numeroRue = ” ” ; 41 } 42 } 43

45 * @param $rue { inOut } nom à v a l i d e r e t , en c a s d ’ e r r e u r , r é i n i t i a l i s e r 46 * @param $ d a t a E r r o r s { inOut } t a b e a u a s s o c i a t i f de remont é e d ’ e r r e u r s . */ 47 protected s t a t i c function v a l i d a t e R u e (&$rue , &$ d a t a E r r o r s ) {

48 i f ( ! E x p r e s s i o n s R e g e x U t i l s : :isValidLatin1WithNumbers ( $rue , 1 , 1 5 0 ) ) {

49 $ d a t a E r r o r s [ ’ rue ’ ] = ” Erreur , l e nom de l a rue \” ” . $ r u e . ” \ ” , ” 50 . ” o b l i g a t o i r e d e v r a i t comporter au p l u s 150 ” 51 . ” c a r a c t è r e s ( a l p h a b é t i q u e s , c h i f f r e s s a n s p o n c t u a t i o n ) ” ; 52 $ r u e = ” ” ; 53 } 54 } 55

56 /* * @ b r i e f permet de v a l i d e r l e compl é ment d ’ a d r e s s e .

57 * @param $complementAddr { inOut } cha î ne à v a l i d e r e t /ou r é i n i t i a l i s e r 58 * @param $ d a t a E r r o r { inOut } t a b e a u a s s o c i a t i f de remont é e d ’ e r r e u r s . */ 59 protected s t a t i c function validateComplementAddr(&$complementAddr ,

60 &$ d a t a E r r o r s ) {

61 i f ( ! E x p r e s s i o n s R e g e x U t i l s : :isValidLatin1WithNumbersAndPunctuation (

62 $complementAddr , 0 , 1 5 0 ) ) {

63 $ d a t a E r r o r s [ ’ complementAddr ’ ] = ” Erreur , l e Compl é ment d ’ a d r e s s e \” ”

64 . $complementAddr . ” \” d e v r a i t comporter au p l u s 150 ” 65 . ” c a r a c t è r e s ( a l p h a b é t i q u e s , c h i f f r e s ou p o n c t u a t i o n ) ” ; 66 $complementAddr = ” ” ; 67 } 68 } 69 70 /* * @ b r i e f permet de v a l i d e r l e code p o s t a l .

71 * @param $ c o d e P o s t a l { inOut } code à v a l i d e r e t /ou r é i n i t i a l i s e r .

72 * @param $ d a t a E r r o r s { inOut } t a b e a u a s s o c i a t i f de remont é e d ’ e r r e u r s . */ 73 protected s t a t i c function v a l i d a t e C o d e P o s t a l (& $ c o d e P o s t a l , &$ d a t a E r r o r s ) {

74 i f ( ! E x p r e s s i o n s R e g e x U t i l s : : i s V a l i d S t r i n g ( $ c o d e P o s t a l , ” /^[0−9]{5} $/” , 5 , 5) ) { 75 $ d a t a E r r o r s [ ’ c o d e P o s t a l ’ ] = ” Erreur , code p o s t a l \” ” . $ c o d e P o s t a l . ” \” i n v a l i d e ” 76 . ” i n v a l i d e ( code p o s t a l de f r a n c e mé t r o p o l i t a i n e s a n s c e d e x n i B. P . ) ” ; 77 $ c o d e P o s t a l = ” ” ; 78 } 79 } 80 81 /* * @ b r i e f permet de v a l i d e r l e nom de l a v i l l e .

82 * @param $ v i l l e { inOut } nom à v a l i d e r e t , en c a s d ’ e r r e u r , r é i n i t i a l i s e r 83 * @param $ d a t a E r r o r s { inOut } t a b e a u a s s o c i a t i f de remont é e d ’ e r r e u r s . */ 84 protected s t a t i c function v a l i d a t e V i l l e (& $ v i l l e , &$ d a t a E r r o r s ) {

85 i f ( ! E x p r e s s i o n s R e g e x U t i l s : : i s V a l i d L a t i n 1 ( $ v i l l e , 1 , 1 5 0 ) ) { 86 $ d a t a E r r o r s [ ’ v i l l e ’ ] = ” Erreur , l e nom de l a v i l l e \” ” . $ v i l l e . ” \” , ” 87 . ” o b l i g a t o i r e , d e v r a i t comporter au p l u s 150 ” 88 . ” c a r a c t è r e s ( a l p h a b é t i q u e s s a n s p o n c t u a t i o n ) ” ; 89 $ v i l l e = ” ” ; 90 } 91 } 92

93 /* * @ b r i e f permet de v a l i d e r l e nom du pays

94 * @param $pays { inOut } nom à v a l i d e r e t , en c a s d ’ e r r e u r , r é i n i t i a l i s e r 95 * @param $ d a t a E r r o r s { inOut } t a b e a u a s s o c i a t i f de remont é e d ’ e r r e u r s . */ 96 protected s t a t i c function v a l i d a t e P a y s (&$pays , &$ d a t a E r r o r s ) {

98 $ d a t a E r r o r s [ ’ pays ’ ] = ” Erreur , l e nom du Pays \” ” . $pays . ” \ ” , o b l i g a t o i r e , 99 . ” d e v r a i t comporter au p l u s 100 c a r a c t è r e s ” 100 . ” ( a l p h a b é t i q u e s s a n s p o n c t u a t i o n ) ” ; 101 $pays = ” ” ; 102 } 103 } 104 105 /* * @ b r i e f V a l i d a t i o n d e s a t t r i b u t s d ’ une i n s t a n c e d ’ Adresse

106 * ( par exemple à p a r t i r d e s donn é e s s a i s i e s dans un f o r m u l a i r e v i a $_REQUEST) 107 * Pour chaque a t t r i b u t de l a c l a s se , s i une e x c e p t i o n e s t g éné r é e l o r s de l a 108 * v a l i d a t i o n de l ’ a t t r i b u t , l e message d ’ e x c e p t i o n e s t a j o u t é dans un t a b l e a u 109 * a s s o c i a t i f d ’ e r r e u r s .

110 * Ces messages d ’ e x c e p t i o n s o n t a i n s i r e t o u r n é s v e r s l e c o n t r ô l e u r . 111 * @param $ d a t a E r r o r s { o u t } t a b l e a u a s s o c i a t i f d ’ e r r e u r s

112 * @param $ a d r e s s e { inOut } i n s t a n c e d ’ Adresse */

113 public s t a t i c function v a l i d a t e I n s t a n c e (& $ d a t a E r r o r s , &$ a d r e s s e ) {

114 // Cré a t i o n du t a b l e a u d e s e r r e u r s v i d e : 115 $ d a t a E r r o r s = array ( ) ;

116 // V a l i d a t i o n d e s d i f f é r e n t s a t t r i b u t s

117 s e l f : : v a l i d a t e I d A d r e s s e ( $ a d r e s s e−>idAdresse , $dataErrors ) ;

118 s e l f : : v a l i d a t e I d P e r s o n n e ( $ a d r e s s e−>idPersonne , $dataErrors ) ;

119 s e l f : :validateNumeroRue ( $ a d r e s s e−>numeroRue , $dataErrors ) ;

120 s e l f : : v a l i d a t e R u e ( $ a d r e s s e−>rue , $dataErrors ) ;

121 s e l f : :validateComplementAddr ( $ a d r e s s e−>complementAddr , $dataErrors ) ;

122 s e l f : : v a l i d a t e C o d e P o s t a l ( $ a d r e s s e−>codePostal , $dataErrors ) ; 123 s e l f : : v a l i d a t e V i l l e ( $ a d r e s s e−>v i l l e , $dataErrors ) ; 124 s e l f : : v a l i d a t e P a y s ( $ a d r e s s e−>pays , $dataErrors ) ; 125 } 126 127 /* * @ b r i e f O b t e n t i o n d ’ une i n s t a n c e v a l i d é e de l a c l a s se Adresse 128 * ( par exemple à p a r t i r d e s donn é e s s a i s i e s dans un f o r m u l a i r e ) . 129 * C e t t e mé t h o d e a t t e n d un t a b l e a u a s s o c i a t i f ( t y p i q u e m e n t $_REQUEST) . 130 * Les v a l e u r s du t a b l e a u s o n t n e t t o y é e s ou é chapp é e s

131 * par une p o l i t i q u e de f i l t r a g e d é f i n i e dans V a l i d a t i o n U t i l s .

132 * Un paramètre p a s s é par r é f é r e n c e r e t o u r n e l e s messages d ’ e x c e p t i o n s . 133 * La mé t h o d e c r é e une i n s t a n c e e t v a l i d e s e s a t t r i b u t s a v e c

134 * s e l f : : v a l i d a t e I n s t a n c e ( ) .

135 * Ces messages d ’ e x c e p t i o n s o n t a i n s i r e t o u r n é s v e r s l e c o n t r ô l e u r . 136 * @param $ d a t a E r r o r s { o u t } t a b l e a u a s s o c i a t i f d ’ e r r e u r s

137 * @param $ i n p u t A r r a y t a b l e a u a s s o c i a t i f dont l e s c l e f s c o n t i e n n e n t l e s noms

138 * d e s a t t r i b u t s d ’ Adresse .

139 * Passage par r é f é r e n c e pour é v i t e r une r e c o p i e .

140 * @param $ p o l i c y = SANITIZE_POLICY_DISCARD_HTML p o l i t i q u e de n e t t o y a g e 141 * @return une i n s t a n c e d ’ Adresse v a l i d é e

142 * @see A d r e s s e V a l i d a t i o n 143 * @see V a l i d a t i o n U t i l s */

144 public s t a t i c function g e t V a l i d I n s t a n c e (& $ d a t a E r r o r s , &$inputArray ,

145 $ p o l i c y = \CoursPHP\ C o n t r o l e u r \ V a l i d a t i o n U t i l s 146 : :SANITIZE_POLICY_DISCARD_HTML_NOQUOTE) { 147 // C o n s t r u c t i o n d ’ une i n s t a n c e f i l t r é e s u i v a n t l a p o l i t i q u e 148 A d r e s s e V a l i d a t i o n : : v a l i d a t i o n I n p u t ( $inputArray , $ a d r e s s e , $ p o l i c y ) ; 149 // V a l i d a t i o n s u i v a n t l a l o g i q u e mé t i e r 150 s e l f : : v a l i d a t e I n s t a n c e ( $ d a t a E r r o r s , $ a d r e s s e ) ; 151 return $ a d r e s s e ; 152 }

153 } 154 ?>

Dans ce chapitre, nous proposons une conception de classes métiers et classes d’utilitaires pour générer des vues HTML comportatnt des formulaires. La gestion des données saisies par l’utilisateur nous conduit, au vu du chapitre 4, à gérer plus rigoureusement le filtrage. Nous nous appuierons pour cela sur les utilitaires présentés dans la partie 5.2.