←back to Blog

Faire des requêtes sécurisées sous WordPress 2.5 ! Utilisation de la méthode $wpdb->prepare !

959811_88673421 Parlons un peu sécurité !

WordPress, comme tout logiciel informatique, est de plus en plus soumis a des attaques diverses et variées… Pour contrer ce genre de désagrément, WP utilise plusieurs mécanismes:

  • Gestion des droits
  • Un nouvel algorithme de cryptage des mots de passe pour WordPress 2.5
  • La gestion de "nonce" permettant de vérifier la provenance lors d’une action dans l’administration.

La grande nouveauté de cette version 2.5, c’est l’ajout d’une méthode permettant de protéger rapidement et efficacement les requêtes SQL d’une technique très remployées, j’ai nommé les injections SQL.

Avant WordPress 2.5, c’était un peu l’anarchie. En effet, chaque plugin dispose de son propre mécanisme de protection, plus ou moins efficace et plus ou moins testé…

Afin de remettre les choses a plats, les développeurs ont ajouté la méthode "prepare" à la classe d’accès a la base de données "wpdb".

Cette méthode bouscule les habitudes sur plusieurs aspects, pour bien comprendre le fonctionnement, je vais décortiquer une requête SQL de WordPress avec l’ancienne et la nouvelle méthode !

Ancienne méthode

Dans cet exemple, je vais prendre la requête SQL utilise lors de l’insertion d’un article dans la base de donnes. Cette requête permet de vérifier que l’identifiant de l’article (ou slug) est bien unique, le cas échéant WP rajoutera un suffixe mais peu importe… Le sens de la requête n’a aucun intérêt dans cette démonstration !

Voici la requête:

$post_name_check = $wpdb->get_var("SELECT post_name FROM $wpdb->posts WHERE post_name = '$post_name' AND post_type = '$post_type' AND ID != '$post_ID' AND post_parent = '$post_parent' LIMIT 1");

Note: vous pouvez trouver la requête dans le fichier "wp-includes/post.php", à la ligne 701.

Comme vous pouvez le constater, la requête fait appel à 4 variables dynamiques:

  • $post_name
  • $post_type
  • $post_ID
  • $post_parent

Ces variables sont des sources potentielles d’injections SQL… Pour être sûr de leur contenu, il est impératif de les sécuriser une par une… Cela implique plus de code… et surtout un code répétitif à souhait qui perd en lisibilité !

La nouvelle méthode !

Voici la même requête sous WP 2.5:

$post_name_check = $wpdb->get_var($wpdb->prepare("SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d AND post_parent = %d LIMIT 1", $post_name, $post_type, $post_ID, $post_parent));

Note: vous pouvez trouver la requête dans le fichier "wp-includes/post.php", à la ligne 1267.

Que remarquons-nous ?

  1. Avant d’effectuer la requête SQL (méthode "get_var"), nous utilisons la méthode "prepare"
  2. Nous n’avons plus de variables directement dans la requête SQL
  3. La méthode "prepare" fonctionne de la même façon que les fonctions PHP "sprintf" ou "printf" (chaînes formatées)
  4. Le nombre de paramètre de la méthode "prepare" est infini.
  5. Le code de la requête SQL est plus lisible

Comment ça marche ?

Dans le code de la requête SQL, à la place des variables PHP, nous plaçons des marqueurs. Ces marqueurs débutent toujours par un pourcentage.

  • %s pour une chaîne de caractère
  • %d pour un nombre entier
  • La suite des marqueurs sur php.net.

A ce moment de l’article, pour ceux qui ont tout compris, vous vous dites: "Quelles différences avec l’ancienne méthode, les marqueurs ont les mêmes inconvénients que les variables PHP…" et "Pourquoi faire une méthode prepare alors qu’il existe déjà la fonction PHP sprintf…"

C’est précisément ici que la méthode agit… Contrairement à la fonction sprintf, qui ne fait que remplacer bêtement les variables.

La méthode "prepare" passe par une étape intermédiaire, la sécurisation des variables:

  1. Suppression des quotes simples et doubles de la requête
  2. Ajout des guillemets entre les variables PHP pour respecter la syntaxe SQL
  3. Utilisation de la méthode "escape" pour protéger les variables des injections SQL

Conclusion

Vous l’aurez bien compris… L’intérêt majeur de cette fonction est de gagner du temps lors de la création des requêtes SQL ! (tout en les sécurisant)

Grâce à son fonctionnement "à la printf", le code de vos extensions gagnera en lisibilité, en légèreté, et la sécurité sera assurée…

Il ne reste plus qu’à attendre les nouvelles versions de vos extensions préférées pour WordPress 2.5 !

(Extensions = Plugins, préparez vous mentalement… C’est la nouvelle traduction française dans WordPress 2.5)

4 réponses à “Faire des requêtes sécurisées sous WordPress 2.5 ! Utilisation de la méthode $wpdb->prepare !”

  1. Avatar de Mdkart
    Mdkart

    Ca a l'air très intéressant. J'aimerai bien l'utiliser dans mon plugin DDay que je compte réécrire un peu prochainement.

    Mais je me pose le problème de la compatibilité avec les anciennes versions. Il y a un moyen pour rendre cette méthode valable avec les version < 2.5

  2. Avatar de Onewin Angel
    Onewin Angel

    Salut Merci pour ce post, Je voulais commencer a creer des plugins pour wordpress, cela me sera utile.

    C'est mon premier passsage sur ton site bravo.

    Je voulais juste rajouter si ce n,est pas un sacrilege que DRUPAL utilise de puis longtemps ce type de requetes donc ce n'est pas une si nouveau que ca.

    Je serais interessé a trouver une "Bible de WordPress" Francais ou Anglais, cela me permettrais de devenir un pro developpeur.

    Cela existe deja pour DRUPAL.

    Ok Je suis un fan de Drupal, Mais la version 2.5 de WP m'a convaincu du potentiel de WordPress.

    Bravo a toute l'equipe WordPress!