Contenu généré par traduction automatique

Le texte de cette page provient d'une traduction automatique. Une révision par un humain est prévue.

Avec les scripts PHP, les aspects de sécurité sont essentiellement centrés sur deux points :  Cross-Site-Scripting (CSS ou XSS) et empêcher l'espionnage des données ou l'infiltration du code. Pour ce faire, il est particulièrement nécessaire de vérifier toutes les entrées provenant de l'extérieur. Cela concerne les données transférées dans l'URL, les données par formulaire, les cookies et les fichiers chargés.

Veuillez noter La liste des mesures de sécurité mentionnées ici ne doit pas être considérée comme un concept de sécurité complet, mais sert uniquement à détecter les risques fondamentaux.

Un concept de sécurité couvre toujours le logiciel dans son intégralité et couvre systématiquement tous les domaines du traitement des données. La sécurisation des scripts n'est qu'une composante du concept global.

Insérer le code via include()

Une vulnérabilité courante est tient au fait que la fonction include() est utilisée avec des paramètres variables. Dans ce cas, un attaquant peut injecter du code étranger en passant une URL comme paramètre (ex. http://evil-site.tld/exploit.txt). Ce code, qui peut être librement déterminé par l'attaquant, est alors exécuté comme s'il faisait partie du script. L'attaquant a alors toutes les possibilités du script à sa disposition. Évitez d'appeler include() avec une valeur de variable et utilisez des constantes au lieu de variables. Si l'utilisation de variables est inévitable, filtrez leur contenu en conséquence. Ceci peut être fait avec le code suivant, par exemple.

if (strpos($variable, '://') !== FALSE || strpos($variable, '../') !== FALSE)
die('Illegal string'); 

Ce code vérifie si les chaînes de caractères ://, comme dans http:// ou ftp:// ou ...., comme dans ../.../secret/passwords sont contenus dans la chaîne $variable, et annule l'exécution du script si nécessaire.

Injection SQL

Lorsqu'un script utilise des requêtes de base de données, il est relativement facile pour un attaquant d'injecter du code SQL arbitraire si le script est mal programmé. Cela leur permet de lire, de modifier ou même d'effacer des données auxquelles ils n'ont pas accès autrement.

Supposons que vous utilisiez le code suivant dans un script :

[...]
$sql = "SELECT * FROM addresses WHERE name='".$_GET['name']."'";
$result = mysql_query($sql);
[...]        

Cette requête ou une requête similaire peut apparaître si vous voulez filtrer l'adresse d'un nom particulier à partir d'une table contenant des adresses.
L'attaquant peut maintenant appeler l'URL http://domain.tld/skript.php?name='';DELETE FROM addresses WHERE 1=1 OR name='.
Il en résulte la requête SQL SELECT * FROM addresses WHERE name=''' ; DELETE FROM addresses WHERE 1=1 OR name=''' ;. Tout d'abord, le serveur de base de données sélectionne tous les enregistrements pour lesquels le champ Nom contient une chaîne vide, puis tous les enregistrements sont supprimés de la table. Bien sûr, une telle lacune peut également être utilisée à d'autres fins, la suppression du contenu de la table des matières ne sert que d'exemple ici.

Pour éviter une telle vulnérabilité, les variables dans les requêtes SQL doivent toujours être transformées à l'aide de la fonction mysql_real_escape_string(). Les caractères spéciaux tels que les guillemets simples sont masqués de sorte qu'ils sont interprétés comme faisant partie intégrante de la chaîne de caractères et non comme des caractères de fin de chaîne. Si des valeurs sont passées en dehors des guillemets (par exemple des valeurs numériques), utilisez la fonction intval() si possible. Ceci permet de s'assurer qu'une seule valeur numérique est réellement utilisée, voici un exemple :

Transfert des paramètres dans les URLs

Le passage de paramètres dans les URLs (par exemple http://domain.tld/script.php?id=1) est un moyen courant de passer des arguments aux scripts. Cependant, vous devez toujours être conscient que ces arguments peuvent être définis à volonté par l'utilisateur. Cela signifie que son contenu doit être considéré comme non digne de confiance. Il en va de même pour les données transmises par HTTP post et les cookies.

Ceci est important lorsque vous redirigez d'un script à un autre et que vous passez des paramètres dans l'URL ou sous forme de cookie. Le nouveau script ne peut pas considérer ces paramètres comme fiables, mais doit les vérifier à nouveau. Il est souvent plus facile d'utiliser les fonctions de session de PHP. Les données qui ont été vérifiées et stockées dans la session peuvent maintenant être classées et utilisées de manière sécurisée. L'utilisateur n'a pas la possibilité de modifier directement le contenu de la session.
L'identificateur de session est passé en paramètre avec l'URL. Comme il s'agit d'une chaîne générée au hasard, la probabilité qu'un attaquant puisse deviner l'identifiant d'une session étrangère est extrêmement faible.

Variables globales

Dans les anciennes versions de PHP, les paramètres passés depuis les formulaires ou dans l'URL étaient saisis dans les variables globales. Pour des raisons de compatibilité, cependant, les versions actuelles reproduisent encore ce comportement sur la plupart des systèmes.
Par exemple, si l'URL http://domain.tld/skript.php?variable=content est appelée, une variable avec le nom $variable et le contenu est défini dans le script.

Cela peut devenir un problème si vous utilisez les variables globales en interne sans les initialiser correctement au préalable.

Exemple :

<?php
if ($_GET['password'] == 'secret') {
$admin = true;
}

[...]

if ($admin) {
// Actions réservées à un administrateur qui connaît le mot de passe.
[...]
}
?>

Un attaquant peut simplement appeler l'URL http://domain.tld/skript.php?admin=1 et dispose immédiatement des droits d'administrateur, car la variable $admin renvoie true.

Avec une initialisation correcte, cela peut être évité.

<?php
$admin = false;

if ($_GET['password'] == 'secret') {
$admin = true;
}

[...]

if ($admin) {
// Actions réservées à un administrateur qui connaît le mot de passe.
[...]
}
?>

Maintenant, la valeur précédemment définie pour $admin est d'abord écrasée et n'est définie à true que si le mot de passe a été réellement passé.

Dans d'autres scénarios, l'omission de l'initialisation peut également être utilisée pour des injections SQL, par exemple. Pour cette raison, vous devriez vous habituer à initialiser toutes les variables, bien que la syntaxe de PHP ne l'exige pas.

Cross-Site-Scripting

Le cross site scripting est le cas où un attaquant insère du code JavaScript dans un site étranger pour obtenir des informations auxquelles il n'a normalement pas accès. Ceci peut être utilisé pour accéder à d'autres ID de session ou pour espionner les noms d'utilisateur.
Pour ce faire, un attaquant crée une URL dans laquelle il définit des paramètres qui sont immédiatement affichés dans le texte de la page. Si ce texte contient maintenant du code script, il est exécuté dans le contexte de sécurité de la page, par exemple, il peut lire les cookies qui ont été mis en place par cette page. Le danger de ce type d'attaque est qu'elle est presque invisible pour l'utilisateur lorsqu'elle se produit dans un cadre caché.

La solution est d'utiliser la fonction htmlentities() dans le script pour toutes les variables à sortir (en particulier celles qui contiennent des entrées utilisateur).
Ceci remplace les caractères ayant une signification spéciale en HTML, tels que < >,">',", avec les entités correspondantes. Cette mesure simple vous permet d'éliminer la plupart des possibilités d'attaque pour Cross-Site-Scripting.