Taint Mode pour PHP ? (Mode de marquages des corruptions de données)

Wietse Venema, le créateur du MTA POSTFIX, a posté une proposition pour un « Taint Mode » sur la mailing-list de PHP-internals. Avant de commenter sa proposition, je voudrais donner une introduction courte au sujet de ce qu'est un « Taint mode » : Considérez les 2 types principaux de données que vous employez dans une application : La séparation la plus significative que vous pouvez faire est entre les données « entrantes » et les données « sortantes ».

Les données « entrantes » sont toutes celles qui sont reçues/demandées/injectées dans votre application, par exemple les tableaux $_GET/$_POST/$_COOKIE/... dans votre application PHP contiennent des données « entrantes », mais également tout que vous recevez d'une base de données, un fichier, un shell ou de n'importe où ailleurs. Les données « sortantes » (en opposition) sont tout ce que vous fournissez aux ressources externes, comme un echo d'une chaîne, en envoyant une requête à une base de données, en soumettant des arguments à une commande shell ou en écrivant dans un fichier.

Comme vous devriez savoir, la majeure partie (toutes) de vos données « entrantes » sont potentiellement dangereuse et peu sûre. Ceci pourrait s'appliquer plus aux tableaux super globaux et moins aux fichiers et aux résultats de base de données. Mais si vous cherchez un peu plus profondément et considérez que votre base de données pourrait être compromise ou quelqu'un a manoeuvré un fichier avec malveillance, ce genre de données « entrantes » contient aussi un risque potentiel au niveau de la sécurité. Donc, tous les genres de données « entrantes » doivent être considérés potentiellement mauvais (je pense que c'est l'incantation la plus fondamentale du développement d'application de Web). En revanche, les données « sortantes » (le plus généralement, si elles dépendent des données entrantes) sont potentiellement peu sûres pour vos utilisateurs et/ou votre application directement (injection de XSS, de SQL,...).

Pour le moment de la considération, le « Taint Mode » entre en jeu : Chaque à bit unique des données « entrantes » est peu sûr, il est «tainted» c'est à dire « corrompu ». En Taint mode, votre interpréteur marque toutes les variables entrantes comme « corrompues ». Si vous effectuez alors une opération potentiellement peu sûre avec les données corrompues, on vous le notifiera. Par exemple, si vous utilisez une variable venant d'un POST directement dans une requête SQL, vous êtes en train d'utiliser de la donnée corrompue entrante, et vous ouvrez une faille sécurité. En « Taint mode », l'interpréteur de PHP s'arrêterait là vous informant sur ce problème. Pour remédier à cette faille, vous devez employer un mécanisme spécifique pour « nettoyer » vos données avant de les employer.

Dans notre exemple, ce serait d'échapper aux données correctement avant de l'employer dans le SQL ou d'employer l'attache variable.

Le même aspect s'applique dans l'autre sens : Si vous récupérez des données dans une base de données et d'un simple echo vous tentez de les présenter à l'utilisateur, il pourrait contenir du code HTML peu sûr et du code de script client. Ces données sont aussi corrompues, vous devez aussi échapper les caractères HTML correctement (htmlspecialchars ()), avant de les envoyer au navigateur.

Le texte de Tobias s'étend ensuite sur la proposition de Wietses que je ne traduis pas ici. L'important pour moi était d'enfoncer le clou sur cette problématique des données entrantes.

Une solution palliative souvent rencontrée est de toujours travailler avec un tableau personnel de données nettoyées.

$cleanData['foo'] = lafonctionquifaitlenettoyage($_REQUEST['foo']);

Ce tableau ayant été nettoyé en début de script.

Une autre technique est une technique de lecture.

Si vous avez une donnée entrante à droite d'une affectation avant d'avoir été à gauche (à l'occasion de quoi un nettoyage aura été fait) c'est qu'il y a un problème.