Serveur d'impression

Perens Unicode Forensics – Serveur d’impression

Le 4 décembre 2019 - 6 minutes de lecture

Index de l'article

Perens Unicode Forensics

Pourquoi UTF?

Page 1 sur 2

Les encodages de caractères et les incompatibilités d'environnement gênent-ils vos données? Pourquoi cela se produit-il et que faire?

Un message SOAP est remis à un serveur Apache qui exécute un script CGI Perl basé sur SOAP :: Lite qui agit en tant que serveur SOAP. Le script interagit avec Ingres, lisant et insérant des données. Perl et Ingres sont tous deux à l’accord pour parler le grec iso8859 / 7.

Le problème était que le même script CGI produisait des résultats différents lorsqu'il était exécuté sur des serveurs différents. Dans le premier cas, les caractères grecs envoyés par le client et consommés par le serveur entrent dans la base de données comme il se doit, tandis que dans le second cas, les mêmes données sous le même flux de travail se terminent en "garbage". Par exemple, le caractère grec A majuscule ou alpha se termine par la séquence " 201".

Les serveurs

Le serveur A est celui qui est erroné. Ses spécifications sont:

  • Centos 6.5
  • Apache / 2.2.15 (Unix)
  • perl5 (révision 5 version 10 subversion 1)
  • SOAP :: Lite 1.27

Le serveur B précède de plusieurs années le serveur A et porte l'installation initiale. Il produit les résultats escomptés. Ses spécifications sont:

  • Centos 5.6
  • Apache / 2.2.3
  • perl5 (révision 5 version 8 subversion 8)
  • SOAP :: Lite 0.714

Le code échantillon

La source de script CGI, test.cgi, Est fortement simplifié et allégé à des fins de démonstration, mais révèle toujours le concept sous-jacent:

#! / usr / bin / perl

utilisez SOAP :: Transport :: HTTP;

SOAP :: Transport :: HTTP :: CGI-> dispatch_to ('test') -> handle ();

test de l'emballage;

sous-sélection

Et avant de crier INJECTION SQL !! oui je sais, code hérité … mais de toute façon le serveur n'est pas ouvert au public et n'est accessible que "localement" par VPN.

Maintenant au client, test.pl:

utilisez SOAP :: Lite + trace;
mon $ soap = SOAP :: Lite->uri ("http://192.168.10.205/test") ->

proxy ("http://192.168.10.205/cgi-bin/test.cgi") ->
select ("16/09/2019 17:04:00", "16/09/2019", "13/09/2019 13:44:09", "Α", "C", 3519999) -> résultat;

print "result is", @ $ soap;

Notez cet argument "UNE" est en grec tandis que le reste est en anglais. Les deux serveurs sont définis sur la locale el_GR.ISO8859-7, par exemple LANG = el_GR.ISO8859-7, etc.

L’hypothèse était que, puisque le script avait été copié et collé d’un serveur à l’autre, deux environnements * presque * identiques, en tant que tel, tout fonctionnerait parfaitement, mais ce n’était malheureusement pas le cas.Au contraire elle a jeté les bases d'un parcours de débogage au cœur de la codification des caractères et de leur traitement par Perl.

Tester les environnements

Je me suis donc mis à tester le nouveau serveur A.

L'utilisation de test.pl pour envoyer le paquet SOAP à test.cgi a entraîné l'écriture suivante dans la base de données (le jeu de caractères de la base de données est fixé sur iso-8859-7):

| date1 | date2 | date3 | grec | anglais | id

16/09/2019 17:04:00 │ 16/09/2019 | 13/09/2019 13:44:09 | 201 201 | C | 3519999

La capitale grecque finissait comme "Γ 201" … c'est la capitale grecque Gamma plus 201

Au contraire sur le serveur B:

| date1 | date2 | date3 | grec | anglais | id
16/09/2019 17:04:00 │ 16/09/2019 | 13/09/2019 13:44:09 | Α | C | 3519999

La capitale grecque Alpha finissait bien par devenir le grec "A".

Pourquoi donc? Quelle est la faute? Perl, SOAP :: Lite, le système d'exploitation?

Il est temps de faire de la médecine légale

Faisons un:

sélectionnez hex (grec) de la table de test où id = 3519999

201 C3812020202020202020│

Il semble que le seul octet "A" se termine par la séquence de deux octets C3 et 81, le reste étant un espace blanc.

Cela désactivait l’alarme UTF8 et invitait à consulter le tableau UTF8 pour la séquence d’octets c381:

U + 00C1 | Á | c3 81 | LETTRE MAJUSCULE LATINE A AIGU

c'est la représentation de latin1 A avec Acute.

Jetons un coup d'oeil au tableau Latin1 / iso-8859-1:

C1 | 193 | Á | 193 | LETTRE MAJUSCULE LATINE A AIGU

Mais comment cela s'est-il mêlé à la lettre majuscule grecque A?

Regardons le tableau grec / iso-8859-7:

C1 | 193 | Α | 913 | LETTRE DE CAPITALE GRECQUE ALPHA

Et nous avons un match! Les deux caractères partagent la valeur décimale 193 ou C1 hexa. Ceci explique comment Perl a reçu l'octet correct sous-jacent, mais a pensé qu'il était en iso-8859-1, valeur par défaut, et non en iso-8859-7.

En d'autres termes, SOAP :: Lite reçoit l'octet avec la valeur 193 mais le serveur A l'interprète comme
193 en iso-8859-1, LETTRE DE CAPITAL LATINE A AVEC AIGU
tandis que le serveur B
193 en iso-8859-7, LETTRE DE CAPITAL GRECQUE ALPHA

Ce n'est pas la fin de l'histoire, cependant. Cela devient d'autant plus intéressant que ce caractère mono-octet latin1 est par la suite mis à niveau vers UTF8, ce qui expliquerait la séquence à double octet de C381. C381 ne peut pas être inséré dans la base de données sous la forme d'un seul caractère, car la base de données lit l'iso sur un octet et non sur le format UTF sur plusieurs octets; elle est donc décomposée en deux octets, C3 et 81.

Cela est évident lors de l'exécution de la requête SQL à partir du client de terminal SQL:

"select hex (greek) de la table de test où id = 3519999;"

201 C3812020202020202020│

C381 est affiché comme cette séquence sequence 201.

Cela se produit car lorsque le terminal essaie de lire, d’interpréter et d’afficher la valeur sur le moniteur, il lit le code hexadécimal C3, qui dans la table iso7 correspond à la lettre majuscule grecque Gamma ou "".
C3 195 Γ 915 LETTRE DE CAPITALE GRECQUE GAMMA

Bien que l'hex 81 n'existe pas, il est donc non imprimable. Par conséquent, sa valeur octale 201 est affichée.

Commentaires

Laisser un commentaire

Votre commentaire sera révisé par les administrateurs si besoin.