Noplay >>Développement


Niveau: Débutant
Licence de l’article: Free Documentation License

version imprimable

Bonnes pratiques de développement en PHP

le samedi 30 avril 2005 par
Noplay

sommaire

Activez toutes les erreurs
Coupez les erreurs
Les short tags
Les register globals
Nommez les sessions
include_once et require_once
La sécurité
N’utilisez jamais de variable utilisateur dans un include ou un fopen
Protéger vos requêtes SQL
Échappez le HTML et le PHP
Faites un hash des mots de passes
Changer l’id de session
Vérifiez le retour des fonctions systèmes
Style de dévellopement
Remerciements



Le but de cet article est de lister un certains nombre de points important auxquels il faut songer lors du développement en PHP. PHP est tellement simple à apprendre que la majorité des développeurs sont autodidactes et ont parfois pris de (très) mauvaises habitudes.

Activez toutes les erreurs

Lors de la phase de développement il est préférable d’activer tous les warnings : cela vous permettra notamment de connaître les variables non déclarées (ca simplifera le développement).

Coupez les erreurs

Par contre sur un site en production il est recommandé de couper les Warnings afin de ne pas fournir aux pirates de précieuses informations : de plus cela est du plus mauvais effet pour les visiteurs.

Une bonne pratique peut-être de mettre en place un systèmes pour être alerté en cas de soucis. Comme par exemple une notification des erreurs par mail : Un exemple chez Zend

Les short tags

Lorsque vous voulez insérer du code php dans une page n’utilisez pas les short tags :

<?

mais

<?php

. Cela pourrait créer des conflits avec d’autres langages (comme le XML) et l’option est désactivée par défaut.

Les register globals

Avant la version 4.2 de PHP il était possible d’accéder directement aux variables de l’url ou d’un formulaire juste en utilisant leur nom. Pour des raisons de sécurité cette option est désormais coupée par défaut. Mais cette option est toujours activée chez de nombreux hébergeur afin de rester compatible avec les anciens scripts.

Ainsi pour accéder à la variable test de :


http://www.noplay.net/index.php?test=tata

Utilisez $_GET[’test’] plutôt que $test.

Plus d’informations sur phpdebutant

Nommez les sessions

Lors de l’utilisation des sessions avant de faire un session_start utilisez session_name afin de mettre un nom de session propre à votre site ce qui vous évitera de mauvaises surprises sur certains serveur.

session_name

include_once et require_once

Lorsque vous incluez un fichier contenant des classes et des fonctions utilisez include_once si le fichier doit-être inclus de façon conditionnelle et require_once si il doit toujours être inclus.

La seul différence entre require et include est leur comportement en cas d’echec : require provoquera une FATAL ERROR alors que include affichera juste un WARNING.

Les versions once de include et require évite que le fichier soit inclus deux fois ce qui vous permet de ne pas redéfinir les fonctions.

L’explication sur PEAR

La sécurité

Les conseils qui suivent concernent la sécurité de vos scripts ; en effet en PHP l’apprentissage est tellement simple que l’aspect sécurité est souvent négligé.

Je vous recommande les articles de http://www.phpsecure.info (en français pour ne rien gacher :D).

Vous devez toujours garder à l’esprit qu’il ne faut jamais faire confiance à l’utilisateur.

N’utilisez jamais de variable utilisateur dans un include ou un fopen

Ne faites jamais :


include $_GET['page'];
 

En effet un pirate pourrait détourner votre inclusion vers un autre fichier sur votre serveur ou sur un autre. Pour faire ce genre chose, effectuez un controle auparavant comme par exemple :


if ($_GET['page'] == 'forum' || $_GET['page'] == 'news') {
  include $_GET['page'];
}
 

Évidemment vous pouvez faire plus propre.

Protéger vos requêtes SQL

Afin de vous prémunir de l’injection SQL vous devez protéger les variables que vous utilisez dans vos requêtes SQL.

Il est possible d’utiliser pour cela addslashes mais si vous devez insérer des données binaires dans MySQL il vaut mieux utiliser : mysql_real_escape_string.

Note : il est possible que la directive magic_quote de PHP soit activée et protége automatiquement les variables utilisateurs, mais cette option est de plus en plus souvent désactivée pour des raisons de performance. Vous pouvez tester si cette option est activée avec get_magic_quotes_gpc.

Exemple d’utilisation de addslashes :


if (!get_magic_quotes_gpc()) {
    $nom = addslashes($_POST['nom']);
}
else {
    $nom = $_POST['nom'];
}
 

Échappez le HTML et le PHP

Comme pour les requêtes SQL pensez à supprimer le code PHP et HTML afin de vous prémunir contre le Cross Site Scripting, cela peut-être fait avec la fonction htmlspecialchars ou stript_tags. La différence entre stript_tags et htmlspecialchars vient du faite que la première supprime le contenu alors que la seconde le remplace par des caractères protégés.

Lorsque vous utilisez htmlspecialchars faite attention à utiliser le bon charset. Le charset par défaut étant iso-8859-1.

Faites un hash des mots de passes

Ne stockez jamais un mot de passe en clair, en effet si quelqu’un parvenait à s’introduire sur votre site web il aurait directement accés à tous les mots de passe des utilisateurs. Les utilisateurs utilisant bien souvent le même mot de passe partout, les conséquences pourraient être très graves.

Appliquez plutôt une fonction de hashage sur le mot de passe. Celle ci va calculer une chaine de taille fixe à partir du mot de passe avec laquelle il est impossible techniquement de revenir en arrière.

Lorsque l’utilisateur voudra se connecter vous n’aurez qu’à comparer le hash du mot de passe soumis avec celui que vous aviez stocké.

SHA1 MD5

Changer l’id de session

Utilisez la fonction session_regenerate_id afin de changer l’id de session lorsque un utilisateur se connecte. Cela permet de limiter le vol de session.

Vérifiez le retour des fonctions systèmes

Vérifiez toujours le retour de toutes les fonctions systèmes, notament fopen, obstart...

Style de dévellopement

Je vous recommande de lire sur les conventions de codage de PEAR afin d’écrire du code propre et lisible par le plus grand nombre.

http://pear.php.net/manual/fr/stand...

Remerciements

Je tiens à remercier Darzee, Snowcat et Stem pour leurs remarques sur cet article.



commentaires (7 message(s))

hashage cryptographique
le 2 août , par Krunch:
Stocker le hash est mieux que stocker le mdp en clair mais moins bien que de stocker un hash "salé" (HMAC) comme pour les mdp stockés par Apache notamment. Voir par exemple : http://www.ietf.org/rfc/rfc2104.txt http://lasecwww.epfl.ch/php_code/publications/search.php ?ref=Oech04 Et pour une petite introduction à la cryptographie orientée programmation web : http://www.linux-mag.com/content/view/1140/2223/

> Bonnes pratiques de développement en php
le 18 juin , par microtom:

>error_reporting(E_ALL) ;

Préciser que ceci est bien pour PHP4, car pour PHP5 il y a mieux tel que error_reporting = E_STRICT | E_ALL

De plus, activer les rapports d’erreur c’est bien, mais ça ne sert à rien si display_errors = Off :)

voilà

microtom



> Bonnes pratiques de développement en php
le 2 mai , par Frédéric Bouchery:

A part les hébergeurs gratuits, la plupart du temps, il est possible de changer le error_log avec une directive .htaccess

Une solution assez séduisante peut-être de surcharger le errorHandler avec une version pour le développement qui affiche l’erreur mais également plein d’infos comme le debugbacktrace, le contenu de la session, ...etc. et en production, ces même infos sont placées dans un fichier avec une alerte envoyée par email.

En tout cas, placer le error_reporting à "0", c’est une grossière erreur car il ne devient plus possible de savoir s’il y a eu des erreurs graves. Généralement, la génération de ces erreurs graves peut venir d’une utilisation anormale de l’application que l’on n’avait pas testé, et pour cause, un pirate fait certainement "joujou".



Petite erreur ...
le 2 mai , par Max:

Dans le chappitre "Les register globals" vous avez croisez le nom du paramètre et sa valeur.

C’est $_GET[’test’] ou $test qui fonctionnent mais pas $_GET[’tata’] $tata

... http://www.noplay.net/index.php ?test=tata

Utilisez $_GET[’tata’] plutôt que $tata.



> Bonnes pratiques de développement en php
le 1er mai , par Frédéric Bouchery:

hummm ... en production, je laisserai le error_reporting à E_ALL, mais je désactiverai le display_errors et j’activerai le log_errors !

De même, je déconseille l’utilisation de strip_tags, car cette fonction peut avoir un comportement inattendu pour certains utilisateurs qui utilise le symbole "<". Il est préférable d’utiliser htmlspecialchars.



Répondre à cet article

Un message, un commentaire ?

(Pour créer des paragraphes, laissez simplement des lignes vides.)

Lien hypertexte (optionnel)

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d'informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

Qui êtes-vous ? (optionnel)



Webmaster Noplay