PHP Cross-Site Scripting (XSS)


Exemple

Problème

Le script intersite est l'exécution involontaire de code distant par un client Web. Toute application Web peut s'exposer à XSS si elle reçoit des informations d'un utilisateur et les affiche directement sur une page Web. Si input comprend HTML ou JavaScript, le code distant peut être exécuté lorsque ce contenu est rendu par le client Web.

Par exemple, si une partie tierce contient un fichier JavaScript :

// http://example.com/runme.js
document.write("I'm running");

Et une application PHP génère directement une chaîne transmise:

<?php
echo '<div>' . $_GET['input'] . '</div>';

Si un paramètre GET non contrôlé contient <script src="http://example.com/runme.js"></script> la sortie du script PHP sera:

<div><script src="http://example.com/runme.js"></script></div>

Le code JavaScript tiers s'exécutera et l'utilisateur verra "Je cours" sur la page Web.

Solution

En règle générale, ne faites jamais confiance aux données provenant d'un client. Chaque valeur GET, POST et cookie peut être quelque chose et doit donc être validée. Lors de la sortie de l'une de ces valeurs, échappez-les pour qu'elles ne soient pas évaluées de manière inattendue.

Gardez à l'esprit que même dans les applications les plus simples, les données peuvent être déplacées et qu'il sera difficile de suivre toutes les sources. Par conséquent, il est recommandé de toujours échapper à la sortie.

PHP fournit quelques moyens d'échapper à la sortie en fonction du contexte.

Fonctions de filtrage

Les fonctions de filtrage des PHP permettent aux données d'entrée du script php d'être désinfectées ou validées de plusieurs manières . Ils sont utiles lors de la sauvegarde ou de la sortie d'une entrée client.

Codage HTML

htmlspecialchars convertira tous les "caractères spéciaux HTML" dans leurs codages HTML, ce qui signifie qu'ils ne seront alors pas traités en HTML standard. Pour corriger notre exemple précédent en utilisant cette méthode:

<?php
echo '<div>' . htmlspecialchars($_GET['input']) . '</div>';
// or
echo '<div>' . filter_input(INPUT_GET, 'input', FILTER_SANITIZE_SPECIAL_CHARS) . '</div>';

Serait sortie:

<div>&lt;script src=&quot;http://example.com/runme.js&quot;&gt;&lt;/script&gt;</div>

Tout ce qui se trouve dans la <div> ne sera pas interprété comme une balise JavaScript par le navigateur, mais plutôt comme un simple nœud de texte. L'utilisateur verra en toute sécurité:

<script src="http://example.com/runme.js"></script>

Encodage d'URL

Lors de la sortie d'une URL générée dynamiquement, PHP fournit la fonction urlencode pour générer en toute sécurité des URL valides. Ainsi, par exemple, si un utilisateur peut saisir des données qui font partie d'un autre paramètre GET:

<?php
$input = urlencode($_GET['input']);
// or
$input = filter_input(INPUT_GET, 'input', FILTER_SANITIZE_URL);
echo '<a href="http://example.com/page?input="' . $input . '">Link</a>';

Toute entrée malveillante sera convertie en un paramètre d'URL codé.

Utilisation de bibliothèques externes spécialisées ou de listes OWASP AntiSamy

Parfois, vous souhaiterez envoyer du code HTML ou un autre type de code. Vous devrez conserver une liste de mots autorisés (liste blanche) et non autorisés (liste noire).

Vous pouvez télécharger des listes standard disponibles sur le site Web OWASP AntiSamy . Chaque liste est adaptée à un type d'interaction spécifique (ebay api, tinyMCE, etc.). Et c'est open source.

Il existe des bibliothèques existantes pour filtrer le HTML et empêcher les attaques XSS pour le cas général et effectuer au moins des listes AntiSamy avec une utilisation très simple. Par exemple, vous avez HTML Purifier