web-dev-qa-db-fra.com

Exploits de caractères multi-octets - PHP / MySQL

Quelqu'un pourrait-il me signaler un lien contenant des informations sur les exploits de caractères multi-octets pour MySQL? Un ami les a portées à mon attention, mais je n'ai pas pu trouver beaucoup d'informations sur Internet.

20
Matthew S

Résumé. Oui, le problème est que, dans certains encodages de caractères (comme UTF-8), un seul caractère est représenté comme plusieurs octets. Une façon dont certains programmeurs tentent d'empêcher l'injection SQL consiste à échapper toutes les guillemets simples dans les entrées non fiables, avant de les insérer dans leur requête SQL. Cependant, de nombreuses fonctions d'échappement standard ignorent le codage de caractères que la base de données utilisera et traiteront leur entrée comme une séquence d'octets, sans se soucier du fait qu'un seul caractère peut remplir plusieurs octets. Cela signifie que la fonction d'échappement des guillemets interprète la chaîne différemment de la base de données. Par conséquent, il existe certains cas où la fonction d'échappement des guillemets ne parvient pas à échapper des parties de la chaîne que la base de données interprétera comme un codage multi-octets d'un guillemet simple; ou pourrait par inadvertance décomposer un codage de caractères multi-octets d'une manière qui introduit une citation unique là où il n'y en avait pas auparavant. Ainsi, les exploits de caractères multi-octets donnent aux attaquants un moyen de faire des attaques par injection SQL même lorsque le programmeur pensait qu'ils échappaient correctement à leurs entrées dans la base de données.

L'impact. Si vous utilisez des instructions préparées/paramétrées pour former toutes les connexions à la base de données, vous êtes en sécurité. Les attaques multi-octets échoueront. (Sauf bogues dans la base de données et la bibliothèque, bien sûr. Mais empiriquement, ceux-ci semblent être rares.)

Cependant, si vous essayez d'échapper aux entrées non fiables, puis de former une requête SQL de manière dynamique à l'aide de la concaténation de chaînes, vous pouvez être vulnérable aux attaques multi-octets. Que vous soyez en fait vulnérable dépend des détails spécifiques de la fonction d'échappement que vous utilisez, de la base de données que vous utilisez, du codage de caractères que vous utilisez avec la base de données et éventuellement d'autres facteurs. Il peut être difficile de prédire si les attaques multi-octets réussiront. Par conséquent, la formation de requêtes SQL à l'aide de la concaténation de chaînes est fragile et déconseillée.

Détails techniques. Si vous souhaitez en savoir plus sur les détails des attaques, je peux vous fournir un certain nombre de liens qui expliquent les attaques en détail détail. Il existe plusieurs attaques:

  • Attaques de base contre, par exemple, UTF-8 et d'autres encodages de caractères en consommant des barres obliques inverses/citations supplémentaires introduites par la fonction de citation: voir, par exemple, ici .

  • Des attaques sournoises sur, par exemple, GBK, qui fonctionnent en utilisant la fonction de citation pour introduire une citation supplémentaire pour vous: voir, par exemple, le blog de Chris Shiflett , ici , ou - ici .

  • Attaques contre, par exemple, UTF-8, qui dissimulent la présence d'une citation en utilisant un codage non canonique (trop long) non valide de la citation unique: voir, par exemple, ici . Fondamentalement, la manière normale de coder un guillemet simple le fait tenir dans une séquence à un octet (à savoir, 0x27). Cependant, il existe également des séquences multi-octets que la base de données peut décoder comme un guillemet simple et qui ne contiennent pas le 0x27 octet ou toute autre valeur d'octet suspecte. Par conséquent, les fonctions d'échappement standard peuvent ne pas réussir à échapper à ces citations.

20
D.W.

Les attaques multi-octets ne sont pas limitées à l'injection SQL. Dans un sens général, les attaques multi-octets conduisent à une condition de "consommation d'octets" dans laquelle l'attaquant supprime les caractères de contrôle. C'est l'opposé du classique ' or 1=1--, Dans lequel l'attaquant introduit le caractère de contrôle entre guillemets simples. Pour mysql, il y a mysql_real_escape_string() qui est conçu pour résoudre les problèmes d'encodage de caractères. Les bibliothèques de requêtes paramétrées comme PDO utiliseront automatiquement cette fonction. MySQLi envoie en fait les paramètres de la requête comme un élément séparé dans une structure, ce qui évite complètement le problème.

Si une page HTML est rendue via Shift-JIS, il est possible de consommer des caractères de contrôle pour obtenir XSS. Un excellent exemple de cela a été fourni dans " A Tangled Web " (livre fantastique!) À la page 207:

<img src="http://fuzzybunnies.com/[0xE0]">
...this is still a part of the mkarup...
...but the srever dosn't know...
" onload="alert('this will execute!')"
<div>
...page content continues...
</div>

Dans ce cas, le 0xE0 est un octet spécial qui signifie le début d'un symbole de 3 octets. Lorsque le navigateur affiche ce code html, le "> Coulant sera consommé et transformé en un seul symbole Shift-JIS. Si l'attaquant contrôle l'entrée suivante au moyen d'une autre variable, il peut introduire un gestionnaire d'événements pour obtenir l'exécution du code.

5
rook