Formation PUB020 : WordPress, 2023 La base de données WordPress

31.10 Protection contre les injections SQL sous WordPress


À chaque fois qu'un programme effectue une requête SQL à partir de données entrées par l'utilisateur, il s'expose aux injections SQL. Comme donnée entrée par l'utilisateur, on peut retrouver :

  • une valeur saisie dans un formulaire
  • un paramètre dans l'URL (ex : dans l'URL « https://monsite.com/unepage.php?post_id=5 », 5 est la valeur donnée au paramètre post_id)
  • une valeur lue dans un cookie
  • etc.

Les injections SQL sont bien connues des utilisateurs malveillants : lorsqu'une requête SQL utilise une information entrée par l'utilisateur, on tente d'intercepter la requête originale à l'aide de caractères pouvant être interprétés par le SGBD. Tout ceci sera fait dans le but d'effectuer une requête différente de celle qui était originalement prévue.

Par exemple, prenons la requête suivante. Remarquez que j'ai barré une partie de la requête pour bien faire comprendre qu'il ne faut pas faire ceci.

MySQL

SELECT * FROM wp_posts WHERE ID=$_GET['post_id']

Dans cette requête, la valeur de $_GET['post_id'] peut être n'importe quoi. Elle est tirée d'un URL sous la forme « https://monsite.com/unepage.php?post_id=5 ».

Si un utilisateur malveillant modifiait l'URL ainsi : 

« https://monsite.com/unepage.php?post_id=5' OR 1=1; UPDATE wp_users SET user_pass='motdepassecrypte' -- »

La requête exécutée sur le serveur serait la suivante :

MySQL

SELECT post_title FROM wp_posts WHERE ID=5 OR 1=1; UPDATE wp_users SET user_pass='motdepassecrypte'

En entrant un mot de passe de son choix, l'utilisateur malveillant aura ainsi accès à tous les comptes d'utilisateurs du site Web. Ouch !

La plupart des extensions SQL, par exemple mysqli qui est utilisée par WordPress, empêchent nativement de transformer une requête en deux requêtes comme dans cet exemple. Cependant, certaines plus anciennes laissent cette porte ouverte.

Voici un autre exemple d'attaque, cette fois qui passera le test peu importe l'extension SQL utilisée.

MySQL

SELECT post_title FROM wp_posts WHERE ID=5 UNION SELECT CONCAT_WS(CHAR(32,58,32),user(),database(),version())

Cette fois, l'usager malveillant aura accès à de l'information sensible qui l'aidera à mener des attaques plus dangereuses.

Insertion de données

Lors de l'insertion de données, si vous utilisez $wpdb->insert(), vous avez automatiquement une protection contre les injections SQL.

WordPress (PHP)

$resultat = $wpdb->insert(

    $table_matable,

    [

        'champ1' => $nombre,

        'champ2' => $chaine,

    ],

    [

        '%d',

        '%s',

 

    ]

);

Sélection de données

Dans le cas d'une requête SELECT, il faut entourer la requête par un appel à $wpdb->prepare() afin de bénéficier d'une protection contre les injections SQL.

Remarquez que $wpdb->prepare() exige que chaque paramètre soit identifié par son type dans la requête :

  • %d pour nombre entier (digit)
  • %s pour chaîne (string)
  • %f pour nombre à virgule (float)
  • %s pour les dates car elles sont considérées comme des chaînes
WordPress (PHP)

$enreg = $wpdb->get_row(
    $wpdb->prepare(
        "SELECT post_title FROM $wpdb->posts WHERE ID = '%d' ",
        $_GET['post_id']
    )
);

 

Pour plus d'information

« Better Know a Vulnerability: SQL Injection ». Otto on WordPress. http://ottopress.com/2013/better-know-a-vulnerability-sql-injection/

▼Publicité

Veuillez noter que le contenu de cette fiche vous est partagé à titre gracieux, au meilleur de mes connaissances et sans aucune garantie.
Merci de partager !
Soumettre