Retour au blog
Injection SQL WordPress : Proteger et Nettoyer Votre Site
SEO

Injection SQL WordPress : Proteger et Nettoyer Votre Site

Bastien Allain11 mars 202614 min de lecture
wordpressinjection-sqlsecuritebase-de-donneeswaf

Les injections SQL representent l'une des menaces les plus dangereuses pour les sites WordPress. En exploitant des failles dans la validation des donnees, un attaquant peut lire, modifier ou supprimer l'integralite de votre base de donnees. En 2026, les attaques SQLi restent dans le top 3 des vulnerabilites web selon l'OWASP. Ce guide vous explique comment detecter, nettoyer et prevenir les injections SQL sur votre site WordPress.

Comment proteger WordPress contre les injections SQL (7 etapes)
  1. 1

    Auditer les plugins et themesIdentifiez les extensions vulnerables avec WPScan ou Patchstack.

  2. 2

    Scanner la base de donneesRecherchez du contenu malveillant injecte dans les tables WordPress.

  3. 3

    Nettoyer les donnees compromisesSupprimez les lignes injectees et restaurez les valeurs originales.

  4. 4

    Utiliser les requetes prepareesRemplacez les requetes SQL brutes par wpdb::prepare() partout.

  5. 5

    Installer un pare-feu applicatifDeployez un WAF comme Wordfence ou Sucuri pour filtrer les requetes.

  6. 6

    Restreindre les privileges BDDLimitez les droits de l'utilisateur MySQL au strict necessaire.

  7. 7

    Mettre a jour regulierementAppliquez les correctifs de securite des que disponibles.

Qu'est-ce qu'une Injection SQL

Une injection SQL (SQLi) est une technique d'attaque qui consiste a inserer du code SQL malveillant dans une requete envoyee a la base de donnees. Lorsqu'une application web ne valide pas correctement les entrees utilisateur, l'attaquant peut manipuler les requetes pour acceder a des donnees sensibles.

Comment Fonctionne une Injection SQL

Prenons un exemple concret. Un formulaire de recherche WordPress execute cette requete :

SELECT * FROM wp_posts WHERE post_title LIKE '%terme_recherche%';

Si le champ de recherche n'est pas securise, un attaquant peut saisir :

' OR '1'='1' --

La requete devient alors :

SELECT * FROM wp_posts WHERE post_title LIKE '%' OR '1'='1' --%';

Cette requete retourne tous les articles de la base, car la condition '1'='1' est toujours vraie. Le double tiret -- commente le reste de la requete, annulant toute restriction supplementaire.

Les Trois Types d'Injections SQL

Les attaquants utilisent differentes variantes selon le contexte :

TypeDescriptionRisque
Classic SQLiL'attaquant voit directement les resultats dans la pageExtraction massive de donnees
Blind SQLiAucun retour visible, l'attaquant deduit les informations par vrai/fauxPlus lent mais tout aussi dangereux
Union-based SQLiUtilise UNION SELECT pour combiner les resultats avec d'autres tablesAcces a des tables non prevues (wp_users, wp_options)

Il existe egalement les time-based blind SQLi ou l'attaquant utilise des fonctions comme SLEEP() pour deduire des informations en mesurant le temps de reponse du serveur.

Comment WordPress est Cible par les Injections SQL

WordPress utilise MySQL/MariaDB comme base de donnees et interagit avec elle via des milliers de requetes quotidiennes. Plusieurs vecteurs d'attaque existent.

Les Formulaires Non Securises

Les formulaires de contact, de recherche et de commentaires sont des cibles privilegiees. Un plugin qui construit ses requetes SQL en concatenant directement les entrees utilisateur sans les assainir est vulnerable :

// CODE VULNERABLE - Ne jamais faire ceci
$query = "SELECT * FROM wp_users WHERE user_login = '" . $_POST['username'] . "'";
$results = $wpdb->query($query);

Ce type de code permet a un attaquant d'injecter n'importe quelle commande SQL via le champ username.

Les Parametres d'URL

Les parametres GET dans les URLs constituent un autre vecteur courant :

https://exemple.com/?id=1 UNION SELECT user_login,user_pass FROM wp_users--

Les plugins qui utilisent des parametres d'URL pour filtrer du contenu (galeries, portfolios, e-commerce) sont particulierement exposes.

L'API REST WordPress

Depuis WordPress 4.7, l'API REST expose des endpoints qui interagissent avec la base de donnees. Des vulnerabilites dans des plugins utilisant l'API REST ont permis des injections SQL massives. En 2025, plusieurs plugins populaires (plus de 100 000 installations) ont ete touches par des failles SQLi via leurs endpoints REST.

XML-RPC et AJAX

Les requetes XML-RPC (xmlrpc.php) et les handlers AJAX (admin-ajax.php) sont egalement des vecteurs d'injection. Les plugins qui exposent des actions AJAX sans verification adequate des nonces ou de la validation des donnees sont vulnerables.

Detecter une Injection SQL sur WordPress

La detection precoce est cruciale pour limiter les degats. Voici les signes revelateurs et les methodes de diagnostic.

Verifier les Logs d'Erreurs

Examinez vos logs d'erreurs PHP et MySQL pour reperer des requetes anormales :

# Rechercher des tentatives SQLi dans les logs Apache/Nginx
grep -i "union\|select\|concat\|information_schema" /var/log/apache2/access.log
 
# Rechercher les erreurs SQL dans les logs PHP
grep -i "mysql\|sql syntax\|query" /var/log/php_errors.log

Les messages d'erreur SQL visibles sur le front-end sont un signe critique : ils indiquent que votre site expose des informations sur sa structure de base de donnees.

Rechercher des Entrees Suspectes dans la Base de Donnees

Connectez-vous a phpMyAdmin ou utilisez WP-CLI pour inspecter les tables critiques :

-- Rechercher du code suspect dans wp_options
SELECT option_name, option_value
FROM wp_options
WHERE option_value LIKE '%eval(%'
   OR option_value LIKE '%base64_decode%'
   OR option_value LIKE '%<script%'
   OR option_value LIKE '%<?php%';
 
-- Verifier les options transients suspectes
SELECT option_name, LENGTH(option_value) as taille
FROM wp_options
WHERE option_name LIKE '_transient_%'
AND LENGTH(option_value) > 10000
ORDER BY taille DESC;

Verifier les Comptes Utilisateurs Non Autorises

Les attaquants creent souvent des comptes administrateurs via injection SQL :

-- Lister tous les administrateurs
SELECT u.user_login, u.user_email, u.user_registered
FROM wp_users u
INNER JOIN wp_usermeta m ON u.ID = m.user_id
WHERE m.meta_key = 'wp_capabilities'
AND m.meta_value LIKE '%administrator%'
ORDER BY u.user_registered DESC;

Tout compte administrateur que vous ne reconnaissez pas est un indicateur de compromission, l'un des signes les plus courants d'un site WordPress pirate. Verifiez particulierement les comptes crees recemment.

Utiliser des Outils de Scan

Plusieurs outils peuvent detecter les vulnerabilites SQLi sur votre site :

  • WPScan : scanner de vulnerabilites WordPress en ligne de commande
  • sqlmap : outil automatise de detection et d'exploitation SQLi (pour tests uniquement)
  • Wordfence / Sucuri : plugins de securite avec detection en temps reel
  • Acunetix / Burp Suite : scanners de securite web professionnels
# Scanner les vulnerabilites avec WPScan
wpscan --url https://votre-site.com --enumerate vp,vt
 
# Tester une URL specifique avec sqlmap (uniquement sur vos propres sites)
sqlmap -u "https://votre-site.com/?id=1" --batch --level=3

Nettoyer une Base de Donnees WordPress Apres une Injection SQL

Si votre site a ete compromis par une injection SQL, suivez ces etapes de nettoyage methodiquement.

Etape 1 : Sauvegarder Avant Intervention

Sauvegardez l'integralite de votre base de donnees avant toute modification :

# Export complet de la base de donnees
wp db export backup-avant-nettoyage-$(date +%Y%m%d).sql
 
# Ou via mysqldump
mysqldump -u utilisateur -p nom_base > backup-avant-nettoyage.sql

Conservez cette sauvegarde en lieu sur. Elle pourra servir de reference si le nettoyage cause des problemes.

Etape 2 : Nettoyer la Table wp_options

La table wp_options est une cible privilegiee car elle stocke la configuration du site :

-- Supprimer les options injectees avec du code malveillant
DELETE FROM wp_options
WHERE option_name NOT IN (
    SELECT option_name FROM (
        SELECT option_name FROM wp_options
        WHERE option_value NOT LIKE '%eval(%'
        AND option_value NOT LIKE '%base64_decode%'
        AND option_value NOT LIKE '%<iframe%'
        AND option_value NOT LIKE '%<script%'
    ) AS clean_options
);
 
-- Methode plus sure : identifier d'abord les options infectees
SELECT option_id, option_name, LEFT(option_value, 200) as apercu
FROM wp_options
WHERE option_value LIKE '%eval(%'
   OR option_value LIKE '%base64_decode%'
   OR option_value LIKE '%<script%'
   OR option_value LIKE '%document.write%';
 
-- Puis supprimer par ID specifique
DELETE FROM wp_options WHERE option_id IN (123, 456, 789);

Etape 3 : Nettoyer la Table wp_posts

Les injections dans wp_posts affectent directement le contenu visible de votre site :

-- Detecter les articles contenant du code injecte
SELECT ID, post_title, post_type, post_status,
       LEFT(post_content, 100) as apercu
FROM wp_posts
WHERE post_content LIKE '%<script%'
   OR post_content LIKE '%eval(%'
   OR post_content LIKE '%base64_decode%'
   OR post_content LIKE '%<iframe src=%'
   OR post_content LIKE '%onload=%'
   OR post_content LIKE '%document.cookie%';
 
-- Supprimer le code injecte des articles (exemple avec un pattern specifique)
UPDATE wp_posts
SET post_content = REPLACE(post_content, '<script src="https://malware-site.com/script.js"></script>', '')
WHERE post_content LIKE '%malware-site.com%';
 
-- Nettoyer les meta donnees des articles
SELECT post_id, meta_key, LEFT(meta_value, 200) as apercu
FROM wp_postmeta
WHERE meta_value LIKE '%eval(%'
   OR meta_value LIKE '%base64_decode%'
   OR meta_value LIKE '%<script%';

Etape 4 : Nettoyer la Table wp_users et wp_usermeta

Supprimez les comptes utilisateurs crees par l'attaquant :

-- Identifier les comptes suspects
SELECT u.ID, u.user_login, u.user_email, u.user_registered,
       m.meta_value as role
FROM wp_users u
INNER JOIN wp_usermeta m ON u.ID = m.user_id
WHERE m.meta_key = 'wp_capabilities'
AND (
    u.user_email LIKE '%temp%'
    OR u.user_email LIKE '%test%'
    OR u.user_login LIKE '%admin%'
    OR u.user_registered > '2026-01-01'
)
ORDER BY u.user_registered DESC;
 
-- Supprimer un compte suspect et ses metadonnees
DELETE FROM wp_usermeta WHERE user_id = ID_SUSPECT;
DELETE FROM wp_users WHERE ID = ID_SUSPECT;

Etape 5 : Verifier les Procedures Stockees et Triggers

Un attaquant avance peut creer des triggers ou procedures stockees dans MySQL :

-- Lister tous les triggers de la base
SHOW TRIGGERS;
 
-- Lister les procedures stockees
SHOW PROCEDURE STATUS WHERE Db = 'nom_de_votre_base';
 
-- Lister les evenements programmes
SHOW EVENTS;

Supprimez tout element que vous n'avez pas cree vous-meme.

Etape 6 : Reinitialiser les Mots de Passe

Apres le nettoyage, modifiez tous les mots de passe :

# Modifier le mot de passe admin via WP-CLI
wp user update admin --user_pass="NouveauMotDePasseComplexe123!"
 
# Modifier les cles de salage WordPress
wp config shuffle-salts
 
# Modifier le mot de passe de la base de donnees
# (puis mettre a jour wp-config.php en consequence)

Pour un guide complet de nettoyage couvrant aussi les fichiers, consultez notre guide de nettoyage WordPress en 10 etapes.

Prevenir les Injections SQL sur WordPress

La prevention est toujours plus efficace et moins couteuse que le nettoyage. Voici les mesures essentielles.

Utiliser les Requetes Preparees (Prepared Statements)

La methode la plus efficace contre les injections SQL est l'utilisation de requetes preparees via la classe $wpdb de WordPress :

// METHODE SECURISEE avec $wpdb->prepare()
global $wpdb;
 
// Requete avec un entier
$results = $wpdb->get_results(
    $wpdb->prepare(
        "SELECT * FROM {$wpdb->posts} WHERE ID = %d",
        $post_id
    )
);
 
// Requete avec une chaine
$results = $wpdb->get_results(
    $wpdb->prepare(
        "SELECT * FROM {$wpdb->users} WHERE user_login = %s",
        $username
    )
);
 
// Requete avec plusieurs parametres
$results = $wpdb->get_results(
    $wpdb->prepare(
        "SELECT * FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s LIMIT %d",
        $post_type,
        $status,
        $limit
    )
);

Les placeholders %s (chaine), %d (entier) et %f (flottant) assurent que les valeurs sont correctement echappees avant d'etre inserees dans la requete.

Valider et Assainir les Entrees

WordPress fournit des fonctions de validation natives :

// Assainir les entrees textuelles
$clean_input = sanitize_text_field($_POST['input']);
 
// Assainir les emails
$clean_email = sanitize_email($_POST['email']);
 
// Assainir les URLs
$clean_url = esc_url($_POST['url']);
 
// Valider les entiers
$clean_id = absint($_GET['id']);
 
// Echapper les donnees en sortie
echo esc_html($variable);
echo esc_attr($attribute);

Appliquez le principe de defense en profondeur : validez les entrees cote client ET cote serveur.

Configurer un WAF (Web Application Firewall)

Un pare-feu applicatif filtre les requetes malveillantes avant qu'elles n'atteignent WordPress :

Solution WAFTypePrixSQLi Protection
CloudflareCloudGratuit a 200 EUR/moisRegles OWASP incluses
SucuriCloud199 EUR/anProtection SQLi avancee
WordfencePluginGratuit a 119 EUR/anFirewall avec regles SQLi
ModSecurityServeurGratuit (open source)Regles OWASP configurables

Pour une protection optimale, combinez un WAF cloud (Cloudflare) avec un plugin de securite (Wordfence).

Appliquer le Principe du Moindre Privilege

Configurez les permissions de base de donnees de maniere restrictive :

-- Creer un utilisateur MySQL avec des privileges limites
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'mot_de_passe_complexe';
 
-- Accorder uniquement les privileges necessaires
GRANT SELECT, INSERT, UPDATE, DELETE ON wordpress_db.* TO 'wp_user'@'localhost';
 
-- NE PAS accorder FILE, PROCESS, SUPER, CREATE ROUTINE
-- Ces privileges permettent des attaques avancees
 
FLUSH PRIVILEGES;

L'utilisateur WordPress ne devrait jamais avoir les privileges FILE, PROCESS, SUPER ou GRANT OPTION en production.

Desactiver l'Affichage des Erreurs SQL

Les messages d'erreur SQL revelent la structure de votre base de donnees aux attaquants :

// Dans wp-config.php
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', true);   // Logger les erreurs dans un fichier
define('WP_DEBUG_DISPLAY', false); // Ne pas afficher les erreurs

Les erreurs sont enregistrees dans wp-content/debug.log sans etre visibles par les visiteurs.

Configurer les En-tetes de Securite

Ajoutez des en-tetes HTTP pour renforcer la securite globale :

# Dans .htaccess
<IfModule mod_headers.c>
    Header set X-Content-Type-Options "nosniff"
    Header set X-Frame-Options "SAMEORIGIN"
    Header set X-XSS-Protection "1; mode=block"
    Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'"
    Header set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>

Maintenir WordPress et ses Extensions a Jour

Les mises a jour de securite corrigent les vulnerabilites connues. En 2026, les statistiques montrent que :

  • 94 % des sites WordPress compromis utilisaient des plugins obsoletes
  • Le delai moyen entre la decouverte d'une faille SQLi et son exploitation est de 72 heures
  • Les plugins les plus cibles sont ceux avec plus de 50 000 installations actives

Un contrat de maintenance WordPress permet d'automatiser les mises a jour et de surveiller les failles en continu. Activez les mises a jour automatiques pour les correctifs de securite :

// Dans wp-config.php - activer les mises a jour automatiques mineures
define('WP_AUTO_UPDATE_CORE', 'minor');
 
// Ou via un filtre pour les plugins
add_filter('auto_update_plugin', '__return_true');

Surveiller en Continu les Tentatives d'Injection SQL

La surveillance active permet de detecter les attaques avant qu'elles ne reussissent.

Mettre en Place un Monitoring des Requetes

Configurez la journalisation des requetes lentes et suspectes :

-- Activer le log des requetes lentes (dans my.cnf)
-- slow_query_log = 1
-- slow_query_log_file = /var/log/mysql/slow.log
-- long_query_time = 2
 
-- Verifier les requetes en cours
SHOW PROCESSLIST;

Configurer des Alertes Automatiques

Utilisez des outils de monitoring pour etre alerte en temps reel :

  • Wordfence : alertes email sur les tentatives d'injection bloquees
  • Fail2Ban : bannissement automatique des IP qui tentent des injections SQLi
  • OSSEC : detection d'intrusion au niveau serveur
# Exemple de regle Fail2Ban pour les injections SQL
# Dans /etc/fail2ban/filter.d/wordpress-sqli.conf
[Definition]
failregex = ^<HOST> .*(union.*select|information_schema|concat\(|benchmark\().*$
ignoreregex =

Auditer Regulierement la Securite

Planifiez des audits de securite reguliers :

  • Hebdomadaire : verification des logs de securite et des comptes utilisateurs
  • Mensuel : scan complet avec WPScan et verification des plugins
  • Trimestriel : test de penetration incluant les injections SQL

Pour en savoir plus sur les types de malwares qui peuvent resulter d'une injection SQL reussie, consultez notre guide des malwares WordPress courants en 2026. Si votre site est deja compromis, notre guide sur les fichiers WordPress infectes vous aidera a identifier les fichiers modifies.

Conclusion : La Securite SQL est un Processus Continu

Les injections SQL sur WordPress sont une menace serieuse mais evitable. En combinant requetes preparees, validation des entrees, WAF et surveillance continue, vous reduisez considerablement votre surface d'attaque.

Les points essentiels a retenir :

  • Utilisez toujours $wpdb->prepare() pour les requetes SQL dans vos developpements WordPress
  • Deployez un WAF (Cloudflare + Wordfence) pour bloquer les tentatives avant qu'elles n'atteignent votre site
  • Surveillez vos logs et configurez des alertes sur les patterns d'injection
  • Maintenez tout a jour : WordPress core, plugins, themes et PHP
  • Limitez les privileges de l'utilisateur MySQL de WordPress

Si votre site a deja ete victime d'une injection SQL et que vous avez besoin d'une intervention professionnelle, notre equipe est specialisee dans le nettoyage de malwares WordPress et peut restaurer votre site en toute securite.

Articles similaires