jeudi, novembre 21, 2024
Nom d'utilisateur : Mot de passe :
Home > Dossiers > Dossiers PHP > Sécurité PHP : les bases
[NEWS]
Envoyé par unreal
Le PHP n'a pas une très bonne réputation en matière de sécurité. Cette mauvaise réputation est souvent le résultat de négligence de la part des développeurs qui ne prennent pas systématiquement les mesures nécessaires pour renforcer la sécurité des sites. Alors voici un petit guide qui rappelle les règles de base.


Surveiller vos variables !

Une des bêtes noires des programmeurs vient du fait que le PHP est un langage non-typé, ce qui veut dire qu'il n'est pas possible de définir le type (int, string...) des variables avant utilisation. Ainsi, une requête SQL comme celle qui suit est très dangereuse :

<?php
$id = $_GET['post_id']; // N'est pas forcément un (int)

// Sans être sûr que $id un (int) on s'expose à de gros soucis !
$sql = 'SELECT c1, c2, c3 FROM t1 WHERE id = ' . $id;
?>


La solution est d'utiliser des casts. Par exemple :

$id = (int)$_GET['post_id']; // $id est forcément un (int)


L'autre bête noire est l'oubli fréquent des addslashes dans les requêtes SQL.

Par exemple :

<?php
$Nom_Utilisateur = $_POST['nom'];
$sql = "SELECT c1, c2, c3 FROM t1 WHERE UserName = '$Nom_Utilisateur'";
?>


Ceci est aussi très dangereux car si jamais '$Nom_Utilisateur' contient un apostrophe, non seulement la requête va échouer, mais en plus il est possible de réaliser une injection SQL, qui pourrait donner au malfaiteur accès complet à la base. Je conseille, donc, de placer les addslashes directement au niveau des requêtes pour éviter de se retrouver avec des \' sur la page Web elle même :

$sql = "SELECT c1, c2, c3 FROM t1 WHERE UserName = '" . addslashes($Nom_Utilisateur) . "'";



Sécurité HTML

Ce n'est pas vraiment une très bonne idée d'autoriser les visiteurs d'un site à saisir directement du HTML car filtrer convenablement ce dernier n'est pas chose facile.
Sans filtrage, le visiteur pourrait insérer du code javascript pour essayer de récupérer des informations sensibles (session PHP) ou pour installer des spywares.
Hélas, filtrer du HTML requière des bonnes connaissances en HTML. Supposons par exemple qu'on autorise la balise <div> pour les blocs de quote (<div class="quote">...</div>), qu'est ce qui empêcherait un visiteur à saisir <div style="...">...</div> ?
Du coup, il faudrait détecter qu'il s'agit bien d'une classe de div autorisée, mais le visiteur pourrait essayer de contourner en mettant <div class="quote" style="font: normal 200pt;">...</div> (notez que ceci est un exemple de HTML non valide, mais qui fonctionne sur certains browsers).
Il faut aussi penser à corriger les erreurs HTML (volontaires ou non) comme les balises laissées ouvertes ou encore les erreurs de syntaxe (comme dans l'exemple précédent).

Toute cette explication pour dire que j'encourage vivement à exploiter un système à base de BBCode qui permet bien plus de contrôle et de sécurité.

Pour info, la classe BBCode qui anime SlashOrg.Net est disponible à cette adresse.


Sécurisation des informations sensibles

Cela peut paraître incroyable, mais il existe encore aujourd'hui des sites qui ne sécurisent pas les informations sensibles des utilisateurs (comme le mot de passe) ; en clair, un site où on vous propose d'envoyer un mot de passe oublié par mail est un site qui ne sécurise pas les mots de passe. La conséquence directe est que n'importe quelle personne ayant accès à la base de données (légitimement ou en exploitant des failles de codage ou de sécurité) peut lire en clair les mots de passe. Ceci est évidemment une mauvaise chose.

Alors qu'est ce qu'on entend par sécurisation ? La méthode la plus simple consiste à hasher les mots de passe avant de les enregistrer dans la base. Le hashage fait intervenir une fonction de codage à sens unique : il est donc impossible (en principe) de retrouver un mot de passe à partir de son hash. En réalité, la seule manière de retrouver le mot de passe est d'essayer toutes les combinaisons, qui peut prendre un temps considérable du moment où on utilise des mots complexes.

L'algo de hashage le plus courant en PHP s'appelle le MD5 (128 bits), mais sachez qu'il en existe d'autres (SHA1, par exemple, offre un codage 160 bits).

Fonctionnement : dans un premier temps, quand l'utilisateur s'inscrit, on stocke son mot de passe sous forme de hash dans la base.

$password = md5($_POST['password']);
$sql = "INSERT INTO users VALUES (..., '$password', ...)";


Ensuite, quand l'utilisateur se logge, on hash à nouveau son mot de passe et on compare à la valeur contenue dans la base :

<?php
$username = addslashes($_POST['username']);
$password = md5($_POST['password']);
$sql = "SELECT username FROM users WHERE username = '$username' AND password = '$password'";
[...] // On recupère le nombre d'entrées dans $no

if ($no == 1) {
$login_ok = true;
} else {
$login_ok = false;
}
?>


Pour exploiter le hashage SHA1, il suffit de remplacer md5() par sha1().


Les sessions

Quand un utilisateur se connecte, il faut pouvoir le "suivre" sur le site pour lui proposer les options adéquates. Pour cela, il convient d'employer les sessions PHP qui permettent de s'assurer que l'utilisateur est bien celui qu'il prétend être. Concrètement, le PHP va envoyer un cookie de session au browser client et stocker une copie de cette session sur le disque du serveur. Ainsi, si jamais l'utilisateur modifie son cookie, la session sera automatiquement détruite. Cette méthode offre donc un excellent niveau de sécurité (tant que le pirate n'arrive pas à intercepter le cookie en sniffant le réseau, par exemple).

Exemple d'utilisation :

<?php
session_start(); // Initialise la session
$_SESSION['nom_de_ma_session'] = 'blablabla'; // Ecriture dans la session
[...]
$ses = $_SESSION['nom_de_ma_session']; // Lecture de la session
[...]
session_unset(); // Libération de toutes les variables de session
session_destroy(); // Destruction de la session
?>


Dans tous les cas, il ne faut jamais stocker des informations sensibles (user ID, nom d'utilisateur, niveau d'utilisateur) dans un cookie non sécurisé, parce que dans ce cas, il est très facile à un utilisateur de modifier le cookie pour se faire passer pour quelqu'un d'autre (un administrateur).


Fin

Comme toujours, n'hésitez pas à faire part de vos remarques. happy.gif

Posté le 10/06/05 à 04:49

Commentaires...[1-5]


RE: Sécurité PHP : les bases

AkyRhO

[AVATAR]

Messages : 0
Inscrit le : 07/12/05
A noter au passage que, pour les rétissants au BBcode, il existe aussi une classe wiki2xhtml très intéressante

Posté le 22/06/05 à 23:41

RE: Sécurité PHP : les bases
Nouveau visiteur
Il serai p-e interressant de parler des liens avec variables visible
ex: 5.php?page=3
Il est fréquent de vois la faute basique mais grave de laissez acces a leur zone admin par exemple 5.php?page=admin
de plus il existe d'autre failles exploitable de cet façon

Posté le 22/07/05 à 20:42

RE: Sécurité PHP : les bases

unreal

[AVATAR]

Messages : 15
Inscrit le : 07/03/04
Nouveau visiteur a dit :

Il serai p-e interressant de parler des liens avec variables visible
ex: 5.php?page=3
Il est fréquent de vois la faute basique mais grave de laissez acces a leur zone admin par exemple 5.php?page=admin
de plus il existe d'autre failles exploitable de cet façon


Effectivement, s'il suffit de faire truc.php?page=admin pour accéder directement à l'espace admin, c'est grave. Par contre, si cela vérifie que l'utilisateur est bien admin et renvoie vers login.php si ce n'est pas le cas, je ne vois absolument pas le soucis.

Posté le 25/07/05 à 03:49

RE: Sécurité PHP : les bases
ToM
Une erreur fatale consiste à inclure un fichier qui contient des mots de passe (ou autre information sensible), sans lui donner une extension .PHP ...

Admettons (soyons fous) que les paramètres de connexion à SQL soient inclus dans un fichier mydb.inc ... Le navigateur affichera le fichier .INC en clair. Alors que si je le nomme mydb.inc.php, même si on pointe directement dessus l'interpréteur PHP n'affichera que les echo ... et pas le reste.


Posté le 22/08/05 à 07:48

RE: Sécurité PHP : les bases
Utile
à moins que tes include soient sécurisés et que tu n'autorises l'include que de fichiers souhaités ;)

(6 mois plus tard mdr, mais j'avais envie de faire ma maligne ) :p

> A nouveau instructif, merci, je vais donc ajouter des addslashes, des (int) devant mes get ou autre, merci

Posté le 05/01/06 à 11:02

Sécurité PHP : les bases
Vous pourriez commenter si vous aviez un compte !