Dynamic-Mess.com


"The world is a dynamic mess of jiggling things..."

Sécuriser PHP

Article posté le 05-02-2014 dans la catégorie PHP

Créer un site sécurisé est tout un art, est assez complexe (bien que parfois complexité soit l'ennemi d'efficacité...) et il est donc impossible de pouvoir prétendre lister en un petit article tous les éléments à mettre en place. Cependant, il est possible de citer les essentiels.

1- Mettre en place une session

La mise en place d'une session est une bonne solution. Il existe soit la solution par session HTTP, soit la solution gérée par PHP, tout aussi efficace. Personnellement j'utilise cette dernière. Les sessions présentent cependant une faille, en cas d'un site tiers pas sécurisé. Ainsi une session encore active, malgré le fait que la page du site soit fermée, pourrait être exploitée par un site tiers, souvent à son insu car lui-même "piraté" (au sens large du terme). On peut se prévenir de ce genre d'ennuis :

De plus, il est possible de faire de l'usurpation d'identitée, par exemple en volant un cookie de session. Il est donc recommandé, pour les échanges de données sensibles, d'utiliser une session securisée.

2- Se méfier de l'IP...

L'autorisation uniquement de certaines adresses IP peut être aussi intéressant. Pour autant, ce type de données n'est pas toujours fiable, la variable $_SERVER[REMOTE_ADDR] pouvant être modifiée

3- ... se fier à l'IP

A l'inverse, si vous avez accès aux paramètres de vos serveurs, une mesure de sécurité interessante peut être de créer un compte spécial d'accès à votre BDD. Ce compte serait dédié à votre site, et ainsi vous pourriez autoriser uniquement la connexion via ce compte depuis l'IP du serveur Web.

De plus, le compte pourrait avoir des droits adaptés (donc limités) à ce dont le site a besoin. Tout cela est possible avec phpMyAdmin.

4- Filtrer les données qui doivent être affichée

Par exemple dans le champ pseudo ou commentaires d'un article. Il faut filtrer ces données : une insertion de code javascript pourrait créer des comportements pas très jolis sur votre site. Vous pouvez utiliser la fonction htmlentities() ou éventuellement htmlspecialchars()htmlentities() est plus "puissante", elle convertit quasiment tout les caractères spéciaux alors que htmlspecialchars() affiche les caractères susceptibles d'être du code HTML/ JavaScript, mais en tant que texte). Une alternative si vous souhaitez quand-même afficher du HTML : la fonction strip_tags() qui permet de faire sauter toutes les balises HTML d'une chaîne, mais avec la possibilité de donner une liste blanche. Exemple :

echo strip_tags(getMessageUtilisateur(), "<i><strong><p><span>") // Autorise les balises <i>, <strong>, <p>... 

Aussi, pensez à filter_sanitize_string qui est probablement la valeur la plus intéressante : elle supprime les balises et tous les caractères spéciaux de la chaine passée en paramètre.

Vérifiez l'existence et le type des données avec des fonctions comme isset(), is_array(), is_string(), is_int(), is_float() , is_bool(), is_numeric() (liste non exhaustive) ou des filtres comme filter_var($_POST['Montant'], FILTER_VALIDATE_INT). Vous avez aussi à disposition des fonctions pour vérifier format des emails, numéros de téléphone... Il y a également les filtres de type CTYPE, par exemple ctype_alnum() qui vérifie qu’une chaîne est alphanumérique (avec son équivalent ctype_alpha()), ou encore la blibliothèque PEAR qui permet de vérifier les formats français (SIRET, numéro de tél...).

5- Préparez ou protégez vos requêtes

Afin d'éviter les injections SQL, il faut protéger vos requêtes, par exemple en les préparant, ou en échappant les caractères spéciaux.

Sous PHP4, il fallait utiliser mysql_real_escape_string sur chaque champ à lire/insérer. J'espère que vous n'utilisez plus cela pour vos nouveaux développements...

Vous pouvez utiliser aussi cette fonction qui enlève tous les caractères qui ne sont pas alphanumériques :

function filtre_mot($leMot)
{
if($leMot==eregi_replace('[^a-z0-9_]', '', $leMot)
 return $leMot;
else
 return false;
}

Maintenant, avec les nouveaux outils, vous pouvez préparer facilement vos requêtes. Voir l'article sur PDO ici.

 

6- Quelques "Trucs"

7- Utiliser un jeton

Afin de protéger ses actions sensibles des attaques de type CSRF, on peut utiliser un jeton.

Ce jeton, généré à la connexion, est stocké dans la session de l'utilisateur. A chaque action sensible, l'utilisateur doit passer par un formulaire, de type POST obligatoirement (ce qui signifie que les requêtes GET sont donc interdites pour ce genre de manoeuvre, et donc qu'un jeton CSRF est inutile dans ce cas). Dans ce formulaire, on place le jeton en champ caché. A la soumission du formulaire, on compare le jeton envoyé et celui stocké en SESSION, donc sur le serveur. Si le jeton est le même, alors on peut commencer à traite le formulaire. Note : cela ne vous dispense pas de vérifier le contenu des champs!

Petit exemple, le formulaire d'abord:

$jeton = md5(uniqid(rand(), TRUE));
$_SESSION['jeton'] = $jeton;
?>
<form action="supprimer-compte.php" method="POST">
<input type="hidden" name="token"
value="<?php echo $jeton; ?>">
<!-- Suite du formulaire -->
</form>

Et le traitement du formulaire :

if (isset($_SESSION['jeton'])
&& isset($_POST['jeton'])
&& $_POST['jeton'] == $_SESSION['jeton'])
{
// Le jeton est valide, on peut donc commencer à traiter le formulaire
}

 

8- Un petit bilan avec phpsecinfo

Le consortium PHPsecinfo fournit gratuitement un kit très simple pour faire un bilan de sécurité de votre serveur, d'un point de vue PHP bien entendu.

 


Cet article vous a plu? Découvrez d'autres articles


Tweet
comments powered by Disqus