[gull] chaine de caractère

Marc SCHAEFER schaefer at alphanet.ch
Tue Dec 16 12:31:02 CET 2003


On Mon, Dec 15, 2003 at 11:17:45PM +0100, Philippe Ney wrote:
> Escaper aussi les ' ou les " (je ne sais plus exactement) en cas d'édition
> multiple pour pas qu'ils se multiplient tout seul comme des grands.

Je préfère le concept de binding: l'idée étant qu'au lieu de passer du
traitement de texte SQL on passe des *variables* aux routines d'accès
aux bases de données.

Ces variables sont alors transmises au moteur SQL d'une manière sûre
(par référence ou par escaping spécifique à chaque base de données).

C'est notamment supporté par Perl/DBI, et je m'étonne que d'autres
langages n'aient pas encore implémenté cela.

Exemple:

   if (do_query($dbh,
                'SELECT id FROM event '
                . 'WHERE (code = ?) '
                . 'AND (latest_inscription_date >= CURRENT_DATE)',
                \@titles,
                \@content,
                [ $event_code ],
                undef,
                $error_reason_reference)) {

ici $event_code n'a pas besoin d'être contrôlé vu qu'il est associé
à la requête par binding ('?') ... encore que cela ne gêne jamais
de le faire.

J'ai conçu quelques wrappers autour de CGI et de DBI qui permettent
de définir des forms par des structures:

      my %person_struct
         = (1 => { 'name'  => 'email_address',
                   'descr' => 'Adresse e-mail',
                   'type'  => 'textfield',
                   'specification' => 'user at fqdn',
                   'check' => \&form_valid_email,
                 },
            2 => { 'name'  => 'type',
                   'descr' => 'Type',
                   'type'  => 'list',
                   'values' => { 'type' => 'list',
                                 'items' => { 'pop_user' => 'Compte POP/IMAP',
                                              'redirection' => 'Redirection' }
                               },
                   'check' => \&form_valid_in_list_values
                 },
            3 => { 'name' => 'country',
                   'descr' => 'Pays',
                   'type' => 'list',
                   'values' => { 'type' => 'function',
                                 'function' => \&form_sql_query,
                                 'dbh' => $dbh,
                                 'query'
                                    => "SELECT id, name || ' (' || CAST(id AS VARCHAR) || ')' as description FROM country",
                                 'label' => 'id',
                                 'value' => 'description',
                                 'default' => 'CH'
                               },
                   'check' => \&form_valid_in_list_values
                 });

La génération de la form se fait par la structure:

         $what = form_create($query,
                             \%person_struct,
                             $myself,
                             { 'mode' => 'create' },
                             $dont_clean,
                             \$error_reason);

Une fois la form traitée, on peut appeler une fonction de validation
qui vérifie que tous les paramètres nécessaires (non optionnels) sont
là et que leur contenu est correct.  La validation peut aussi se faire
en dernier recours dans la base de données.

            if (form_validate_input($query,
                                    \%person_struct,
                                    \%param_hash,
                                    \@incorrect_fields)) {

Si l'application est totalement form-driven, tous ces tests
peuvent se faire automatiquement.

Le traitement de texte SQL est une des causes les plus fréquentes
d'attaques; les méthodes automatisées (genre magic_quotes de MySQL) sont
souvent plus problématiques vu qu'elles provoquent pas mal de problème.

Un autre problème est que toute valeur sous contrôle de l'utilisateur
(p.ex. résultat d'une base de données) doit être protégée à la sortie
(uri_escape() pour les URLs; encode_entities() pour le texte HTML).

Sinon des attaques de cross-scripting sont possibles.

Un autre problème très fréquent en PHP se pose lorsque l'espace des
variables du script est le même que l'espace des variables du forms: un
attaquant peut alors modifier ou du moins initialiser n'importe quelle
variable du script.

PS: les différents packages présentés sont disponibles en package
    Debian sur packages.cril.ch, et en source sur cvs.alphanet.ch
    schaefer/public/packages et sont GPL. Ces scripts ont été
    créés principalement pour améliorer la sécurité et la maintenabilité
    de code (éviter de retaper). Pas pour la beauté visuelle
    ou l'efficacité.

    gppds
       Accès simplifié à PostgreSQL

    cril-perl-support
       Module de configuration, de logging et diverses autres petites
       choses

    cgi-support
       Génération de form, présentation simple de résultats, validation.

    inscription
       Exemple d'implémentation simple (pas encore parfaite, il y a
       encore du travail pour supprimer le code glue).

PS/2: il y a d'autres modules très sympas d'accès SQL en Perl sur CPAN,
      notamment un qui évite complètement le traitement de texte,
      mais je n'ai plus la référence.




More information about the gull mailing list