Échapper aux caractères spéciaux. Échapper à un seul personnage

Généralement des langages de programmation, du texte interfaces de commande, les langages de balisage de texte (HTML, TeX, balisage wiki) traitent du texte structuré dans lequel certains caractères (et leurs combinaisons) sont utilisés comme gestionnaires, y compris ceux qui contrôlent la structure du texte. Dans une situation où il est nécessaire d'utiliser un symbole tel qu'un « symbole de langage courant », utilisez blindage.

Classiquement, le blindage peut être divisé en trois types :

  • un seul caractère s'échappe
  • échapper un groupe de caractères à l'aide de la séquence de caractères « commencer l'échappement », « terminer l'échappement »
  • en utilisant la séquence de commandes « start escaping » et le caractère « end escaping », qui est spécifié avant le début du texte à échapper.
Le manque de protection comme cause de vulnérabilité

Les personnages en fuite attirent Attention particulière, lorsque le texte structuré est généré automatiquement. L'inclusion de données de chaîne arbitraires dans du texte nécessite d'y échapper des caractères de contrôle. Dans le même temps, très souvent, les chaînes réelles ne contiennent pas de tels caractères, ce qui permet au programmeur d'ignorer complètement cette opération et d'obtenir plus un programme simple, qui fonctionne correctement avec « toutes les données de chaîne raisonnables ». Cependant, un tel code simplifié présente une vulnérabilité cachée, car un tiers (l'auteur de la chaîne de données) reçoit une opportunité non autorisée d'influencer structure texte généré. La vulnérabilité devient sérieuse si le texte généré est le programme de quelqu'un d'autre. Traditionnellement, les systèmes utilisant les langages SQL (voir Injection SQL) et HTML (voir Cross Site Scripting) sont sujets à de tels problèmes.

Exemples Échapper un seul caractère
  • Dans le langage de programmation C, les caractères dans les chaînes sont échappés à l'aide du caractère " " placé avant le caractère à échapper. (Dans ce cas, le caractère "\" peut s'échapper, c'est-à-dire que la combinaison "\\" est utilisée pour afficher une barre oblique inverse), le même caractère est utilisé pour échapper les caractères dans ligne de commande Unix.
  • Dans la ligne de commande Microsoft Windows, l'échappement de certains caractères se fait à l'aide du caractère "^" placé avant le caractère à échapper.
Échapper à un groupe de personnages
  • Dans le langage de programmation Python, l'échappement d'un groupe de caractères dans une ligne s'effectue en spécifiant la lettre r (de l'anglais raw - non traité) avant la ligne, c'est-à-dire que les caractères sont échappés par des séquences r" texte d'échappement "
  • Dans le balisage wiki, l'échappement du texte se fait à l'aide de pseudo-balises et . Si vous devez écrire la pseudo-balise elle-même, cela se fait avec des caractères génériques ().
Échappement du texte avec un caractère de fin

Lorsqu'il y a beaucoup de caractères de contrôle dans le texte, il y aura beaucoup de caractères d'échappement, le texte devient lourd. Dans de tels cas, une méthode d'échappement alternative est utilisée - avec le texte final. Dans ce cas, tous les caractères de contrôle ne seront que des caractères (ils ne portent pas de fonction de contrôle) et le texte se termine lorsque le compilateur détecte une certaine séquence - le texte final.

  • Traduction
  • Didacticiel

Injections SQL, falsification de requêtes intersites, XML corrompu... Des choses effrayantes, effrayantes contre lesquelles nous aimerions tous être protégés, mais nous voulons juste savoir pourquoi tout cela se produit. Cet article explique le concept fondamental derrière tout cela : les chaînes et la gestion des chaînes dans les chaînes.

Le principal problème, c'est juste du texte. Oui, juste le texte – c’est le principal problème. Presque tout dans un système informatique est représenté par du texte (qui à son tour est représenté par des octets). Est-il possible que certains textes soient destinés aux ordinateurs, tandis que d'autres soient destinés aux personnes. Mais les deux restent toujours du texte. Pour comprendre de quoi je parle, voici un petit exemple :
Homo Sapiens Supposons qu'il y ait le texte anglais que je ne veux pas traduire en russe.
Vous ne le croirez pas : c'est du texte. Certaines personnes l'appellent XML, mais ce n'est que du texte. Il se peut qu’il ne soit pas approprié de le montrer à l’enseignant. En anglais, mais ce n'est toujours que du texte. Vous pouvez l'imprimer sur une affiche et aller à des rassemblements avec, vous pouvez l'écrire dans une lettre à votre mère... c'est un texte.

Cependant, nous souhaitons que certaines parties de ce texte aient une certaine signification pour notre ordinateur. Nous voulons que l'ordinateur soit capable d'extraire séparément l'auteur du texte et le texte lui-même afin que nous puissions en faire quelque chose. Par exemple, convertissez ce qui précède en ceci :
Supposons qu'il y ait le texte anglais que je ne veux pas traduire en russe par Homo Sapiens
Comment l'ordinateur sait-il comment faire cela ? Eh bien, parce que nous avons très commodément enveloppé certaines parties du texte avec des mots spéciaux entre parenthèses amusantes, comme et. Puisque nous avons fait cela, nous pouvons écrire un programme qui recherche ces parties spécifiques, extrait le texte et l'utilise pour notre propre invention.

En d’autres termes, nous avons utilisé certaines règles dans notre texte pour indiquer une signification particulière que quelqu’un d’autre, suivant les mêmes règles, pourrait utiliser.
D'accord, ce n'est pas si difficile à comprendre. Et si nous voulions utiliser ces drôles de parenthèses qui ont une signification particulière dans notre texte, mais sans utiliser cette signification même ?.. Quelque chose comme ceci :
Homo sapiens< n and y >
Les caractères "" n'ont rien de spécial. Ils peuvent légalement être utilisés n’importe où, dans n’importe quel texte, comme dans l’exemple ci-dessus. Mais qu'en est-il de notre idée de mots spéciaux, comme ? Cela signifie-t-il qu'il s'agit également d'une sorte de mot-clé ? En XML - peut-être oui. Ou peut-être pas. C'est ambigu. Étant donné que les ordinateurs ne sont pas très doués pour gérer les ambiguïtés, quelque chose peut finir par donner un résultat inattendu si nous ne mettons pas les points sur les i nous-mêmes et ne résolvons pas les ambiguïtés.
Ce dilemme peut être résolu en remplaçant les symboles ambigus par quelque chose de sans ambiguïté.
Homo Sapiens Les mathématiques de base nous disent que si x< n and y >n, x ne peut pas être supérieur à y.
Désormais, le texte devrait devenir totalement sans ambiguïté. "".
Définition technique ce - blindage, nous évitons les caractères spéciaux lorsque nous ne voulons pas qu'ils aient leur propre signification particulière.
échapper |iˈskāp| [pas d'objet. ] se libérer [ avec obj. ] ne pas remarquer / ne pas se souvenir [...] [ avec obj. ] Informatique : une raison à interpréter différemment [...]
Si certains caractères ou séquences de caractères dans un texte ont une signification particulière, il doit alors exister des règles précisant comment gérer les situations dans lesquelles ces caractères doivent être utilisés sans invoquer leur signification particulière. Ou, en d’autres termes, s’échapper répond à la question : « Si ces symboles sont si spéciaux, comment puis-je les utiliser dans mon texte ?.
Comme vous pouvez le voir dans l’exemple ci-dessus, l’esperluette (&) est également un caractère spécial. Mais et si on voulait écrire "


Si vos utilisateurs sont bons et gentils, ils publieront des citations d’anciens philosophes, et les messages ressembleront à ceci :

Publié par Platon le 2 janvier à 15h31

On dit que j'ai dit "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."


Si les utilisateurs sont intelligents, ils parleront probablement de mathématiques, et les messages ressembleront à ceci :

Publié par Pascal le 23 novembre à 04:12

Les mathématiques de base nous disent que si x< n and y >n, x ne peut pas être supérieur à y.


Hmm... Encore ces profanateurs de nos parenthèses. Bien avec point technique Ils sont peut-être ambigus, mais le navigateur nous le pardonnera, n'est-ce pas ?


D'accord, STOP, qu'est-ce que c'est ? Un farceur a introduit des balises javascript sur votre forum ? Quiconque consulte ce message sur votre site télécharge et exécute désormais des scripts dans le contexte de votre site qui peuvent faire on ne sait quoi. Et ce n'est pas bon.

À ne pas prendre au pied de la lettre Dans les cas ci-dessus, nous voulons d'une manière ou d'une autre dire à notre base de données ou à notre navigateur qu'il ne s'agit que de texte, n'en faites rien ! En d'autres termes, nous voulons "supprimer" significations spéciales tout le monde caractères spéciaux et des mots-clés à partir de toute information fournie par l'utilisateur, car nous ne lui faisons pas confiance. Ce qu'il faut faire?

Quoi? Qu'est-ce que tu dis, mon garçon ? Oh, vous dites « blindage » ? Et vous avez tout à fait raison, prenez un cookie !
Si nous appliquons l'échappement aux données utilisateur avant de les fusionner avec la requête, alors le problème est résolu. Pour nos requêtes de base de données, cela ressemblera à ceci :
$nom = $_POST["nom"]; $nom = mysql_real_escape_string($nom); $query = "SELECT phone_number FROM utilisateurs WHERE nom = "$name""; $result = mysql_query($query);
Juste une ligne de code, mais désormais plus personne ne peut « pirater » notre base de données. Voyons à nouveau à quoi ressembleront les requêtes SQL, en fonction de la saisie de l'utilisateur :
Alex
SELECT phone_number FROM utilisateurs WHERE nom = "Alex"
McDonalds
SELECT phone_number FROM utilisateurs WHERE nom = "Mc\"Donalds"
Joe" ; utilisateurs de DROP TABLE ; --
SELECT phone_number FROM utilisateurs WHERE nom = "Joe\" ; Utilisateurs DROP TABLE ; --"
mysql_real_escape_string place sans discernement une barre oblique devant tout ce qui pourrait avoir une signification particulière.


Nous appliquons la fonction htmlspecialchars à toutes les données utilisateur avant de les afficher. Le message du parasite ressemble maintenant à ceci :

Publié par JackTR le 18 juillet à 12h56


Notez que les valeurs reçues des utilisateurs ne sont pas réellement « corrompues ». N'importe quel navigateur analysera cela au format HTML et affichera tout à l'écran sous la forme correcte.

Ce qui nous ramène à... Tout ce qui précède démontre un problème commun à de nombreux systèmes : le texte dans le texte doit être échappé s'il n'est pas censé contenir de caractères spéciaux. Lorsque vous placez des valeurs de texte dans SQL, elles doivent être échappées conformément aux règles SQL. Lorsque vous placez des valeurs de texte en HTML, elles doivent être échappées conformément aux règles HTML. Lorsque vous placez des valeurs de texte dans (nom de la technologie), elles doivent être échappées conformément aux règles de (nom de la technologie). C'est tout. Pour être complet, il existe bien sûr d'autres façons de gérer les entrées utilisateur qui peuvent ou non contenir des caractères spéciaux :
  • Validation
    Vous pouvez vérifier si l'entrée de l'utilisateur correspond à une spécification donnée. Si vous avez besoin de saisir un nombre et que l'utilisateur saisit autre chose, le programme doit en informer l'utilisateur et annuler la saisie. Si tout cela est organisé correctement, alors il n'y a aucun risque d'attraper les "utilisateurs DROP TABLE" là où l'utilisateur était censé saisir "42". Ce n'est pas très pratique pour éviter les injections HTML/SQL, car... Vous devez souvent accepter un texte au format libre pouvant contenir des astuces. En règle générale, la validation est utilisée en complément d’autres mesures.
  • Désinfection
    Vous pouvez également supprimer « discrètement » tous les symboles que vous considérez comme dangereux. Par exemple, supprimez simplement tout ce qui ressemble à une balise HTML pour éviter d'être ajouté à votre forum. Le problème est que vous pouvez supprimer des parties parfaitement légales du texte.
    Instructions SQL préparées
    Il existe des fonctions spéciales qui font ce que nous voulions : faire comprendre à la base de données les différences entre la requête SQL elle-même et les informations fournies par les utilisateurs. En PHP, ils ressemblent à ceci :
    $stmt = $pdo->prepare("SELECT phone_number FROM users WHERE name = ?"); $stmt->execute($_POST["nom"]);
    Dans ce cas, l'envoi s'effectue en deux étapes, en distinguant clairement la requête et les variables. La base de données a la capacité de comprendre d’abord la structure de la requête, puis de la remplir de valeurs.

  • Dans le monde réel, tous ces éléments sont utilisés ensemble pour différents niveaux de protection. Vous devez toujours utiliser la validation pour vous assurer que l'utilisateur saisit les données correctes. Vous pouvez ensuite (mais ce n'est pas obligatoire) analyser les données saisies. Si un utilisateur essaie clairement de vous vendre un script, vous pouvez simplement le supprimer. Ensuite, vous devez toujours, toujours échapper aux données utilisateur avant de les insérer dans une requête SQL (il en va de même pour HTML).

3.1 Échapper aux caractères spéciaux

Avant de transmettre les valeurs des variables de formulaire dans les requêtes SQL, vous devez spécialement échapper certains caractères (en particulier une apostrophe), par exemple en plaçant une barre oblique inverse devant eux. La fonction d'insertion est :

mysql_escape_string()

chaîne mysql_escape_string(chaîne $str)

La fonction est similaire à l'autre fonction addlashes(), mais elle ajoute des barres obliques avant un ensemble plus complet de caractères spéciaux. La pratique montre que pour les données texte, vous pouvez utiliser la fonction addlashes() au lieu de mysql_escape_string(). Cela se fait dans de nombreux scripts.

Selon le standard MySQL, les caractères écrits en PHP comme suit : "\x00", "\n", "\r", "\\", """, "" et "\x1A" sont échappés.

Ce numéro inclut un caractère avec le code ASCII zéro, et donc mysql_escape_string() peut être utilisé non seulement pour le texte, mais aussi pour les données binaires. Vous pouvez par exemple lire une image GIF dans une variable (fonction file_get_contents()), puis l'insérer dans la base de données en ayant préalablement échappé tous les caractères spéciaux. Une fois extraite, l’image apparaîtra sous la même forme dans laquelle elle se trouvait à l’origine.

L'échappement de caractères n'est qu'un moyen d'écrire des expressions SQL correctes, rien de plus. Rien n'arrive aux données et elles sont stockées dans la base de données sans barres obliques supplémentaires - telles qu'elles étaient initialement, avant même de s'échapper.

En utilisant mysql_escape_string(), le code de requête précédent ressemble à ceci :

"DELETE FROM table WHERE name="".mysql_escape_string($name).""");

C'est long, maladroit et moche.


3.2 Modèles de requête et espaces réservés

Considérons une autre solution.

Au lieu d'échapper explicitement et d'insérer des variables dans la requête, des marqueurs spéciaux (espaces réservés) sont placés à leur place, ressemblant généralement à ?.

Les mêmes valeurs qui leur seront substituées sont transmises séparément, paramètres supplémentaires.

En utilisant l'hypothétique fonction mysql_qwo, dont le code sera présenté ci-dessous, la requête précédente pourrait être réécrite comme suit :

mysql_qw("DELETE FROM table WHERE nom=?", $nom);

La requête est devenue plus courte et mieux protégée : désormais, lors de l’écriture du code, nous ne pourrons plus manquer accidentellement un appel à la fonction mysql_escape_string() et ainsi tomber dans le piège d’un hacker. Toutes les transformations se produisent automatiquement, à l'intérieur de la fonction.

La liste de lib_mysql_qw.php contient mise en œuvre la plus simple Fonctions mysql_qw() (qw - du wrapper de requête anglais, « query wrapper »).

Il existe également une bibliothèque lib/Placeholder.php qui fournit un support beaucoup plus puissant pour le langage des espaces réservés : http://dklab.ru/chicken/30.html.

Dans la plupart des situations, les capacités fournies par la fonction mysql_qw() sont suffisantes.

Liste lib_mysql_qw.php

mob_info