Si vous avez déjà vu un compte “admin” inconnu apparaître dans WordPress, ou des redirections bizarres vers un site de casino, vous avez vu l’objectif réel des attaques : obtenir une exécution de code, voler des sessions, ou modifier vos contenus pour le SEO.

Prérequis : accès administrateur WordPress, accès à l’hébergement (FTP/SFTP + panel), et idéalement WP-CLI. Travaillez sur WordPress 6.9.4 (avril 2026) et PHP 8.1+. Faites une sauvegarde complète avant toute modification (fichiers + base de données). Ne modifiez jamais les fichiers du cœur WordPress.


La menace

Un site WordPress vulnérable, ce n’est pas “juste” un site qui peut être défiguré. Un attaquant peut :

  • créer un nouvel administrateur et verrouiller le vrai propriétaire hors du site ;
  • injecter du JavaScript (vol de cookies, redirections, popups) ;
  • modifier des articles pour y glisser des liens (spam SEO) ;
  • déposer une porte dérobée (backdoor) dans wp-content/uploads/ ou un plugin ;
  • utiliser votre serveur pour envoyer du spam, miner, ou attaquer d’autres sites.

La plupart des compromis que je dépanne ne viennent pas d’un “hack WordPress” au sens large. Ils viennent d’un trio très banal : plugin vulnérable, identifiants faibles, serveur mal durci. WordPress core est fortement audité, mais votre installation (thèmes, plugins, snippets copiés) l’est beaucoup moins.

En langage simple : votre site est une maison. WordPress, c’est la porte d’entrée principale, plutôt solide. Les plugins, ce sont les fenêtres ajoutées au fil du temps. Une seule fenêtre mal posée suffit.

Les 10 mesures ci-dessous sont celles qui changent vraiment la donne pour un débutant, sans vous transformer en admin sys.


Résumé rapide

  • Mises à jour automatiques (core + plugins + thèmes) et suppression des extensions inutilisées.
  • Comptes protégés : mots de passe uniques, 2FA, limitation des tentatives, pas de partage d’admin.
  • Moins d’accès : permissions de fichiers correctes, désactivation d’édition de fichiers, clés de sécurité renouvelées.
  • Protection applicative : nonces, capacités, validation/échappement des données si vous ajoutez du code.
  • Durcissement serveur : headers HTTP, blocage d’exécution PHP dans uploads, HTTPS strict.
  • Surveillance : logs, scans, WP-CLI pour auditer plugins/users/options.

Code vulnérable — ce qu’il ne faut PAS faire

Le scénario le plus fréquent : vous copiez un “snippet” trouvé sur un forum pour ajouter une fonctionnalité rapide (ex : un endpoint AJAX qui met à jour une option). Ça marche… et ça ouvre une porte.

Petit lexique avant le code :

  • Hook : point d’accroche dans WordPress. Il existe des actions (exécutent du code) et des filtres (modifient une valeur).
  • AJAX WordPress : requêtes HTTP vers admin-ajax.php. Il existe des actions pour utilisateurs connectés (wp_ajax_*) et non connectés (wp_ajax_nopriv_*).
  • Nonce : jeton anti-CSRF. Il ne “sécurise” pas tout, mais évite qu’un tiers déclenche une action à votre place.

Voici un exemple volontairement dangereux. Je l’ai croisé sous des variantes sur des sites avec Elementor/Divi/Avada, parce que ces sites ajoutent souvent des petits endpoints “pratiques”.

<?php
/**
 * EXEMPLE VULNÉRABLE : ne copiez pas ce code.
 * Problèmes :
 * - action accessible aux visiteurs (nopriv)
 * - aucune vérification de nonce (CSRF)
 * - aucune vérification de capacité (n'importe qui peut agir)
 * - donnée non validée
 */
add_action('wp_ajax_nopriv_bpcab_save_setting', 'bpcab_save_setting_vulnerable');
add_action('wp_ajax_bpcab_save_setting', 'bpcab_save_setting_vulnerable');

function bpcab_save_setting_vulnerable() {
    // L'attaquant peut appeler admin-ajax.php?action=bpcab_save_setting
    // et changer une option sensible.
    $value = $_POST['value']; // Non filtré, peut contenir n'importe quoi
    update_option('bpcab_banner_html', $value);

    echo 'ok';
    wp_die();
}

Ce qui se passe en coulisses :

  • Avec wp_ajax_nopriv_*, vous autorisez les visiteurs non connectés à appeler l’action.
  • Sans nonce, un attaquant peut forcer un administrateur connecté à déclencher l’action via une page piégée (attaque CSRF).
  • Sans capability check (vérification de droits), même un abonné pourrait modifier une option globale.
  • Si la valeur est ensuite affichée sur le front (ex : bannière HTML), vous venez d’ouvrir un XSS stocké (script injecté et servi à tous).

Note réaliste : beaucoup de gens collent ce code dans functions.php du thème actif. Puis ils changent de thème (ou passent à un thème enfant) et perdent la fonctionnalité… ou pire, ils réinstallent un vieux thème pour “retrouver le code”, et réintroduisent une faille. Pour la sécurité, évitez les snippets dans le thème.


Code sécurisé — la bonne implémentation

On reprend la même fonctionnalité (enregistrer un réglage), mais correctement. Objectif : seuls les admins peuvent modifier, requête protégée par nonce, données validées, et réponse JSON propre.

Où coller le code ? Le plus propre : un petit plugin custom. Alternative acceptable : un mu-plugin (plugin “must-use”), chargé automatiquement. Évitez un plugin de snippets si vous débutez : une erreur de parenthèse et vous cassez l’admin.

Créez le fichier : wp-content/mu-plugins/bpcab-security-basics.php (créez le dossier mu-plugins s’il n’existe pas).

<?php
/**
 * Plugin Name: BPCAB - Sécurité de base (exemple)
 * Description: Exemple pédagogique : endpoint AJAX sécurisé + durcissement léger.
 * Version: 1.0.0
 * Requires PHP: 8.1
 *
 * Ce fichier doit être placé dans wp-content/mu-plugins/
 * Les mu-plugins sont chargés automatiquement.
 */

defined('ABSPATH') || exit;

/**
 * 1) Enregistre une action AJAX uniquement pour utilisateurs connectés.
 * Ici, pas de wp_ajax_nopriv_* : un visiteur ne peut pas appeler l'action.
 */
add_action('wp_ajax_bpcab_save_setting', 'bpcab_save_setting_secure');

function bpcab_save_setting_secure() {
    /**
     * 2) Vérification CSRF via nonce.
     * - Le nonce doit être envoyé depuis le front/admin.
     * - Le nom "bpcab_settings" doit correspondre à celui utilisé à la création.
     */
    check_ajax_referer('bpcab_settings', 'nonce');

    /**
     * 3) Vérification des droits.
     * manage_options = capacité typique des administrateurs.
     */
    if (!current_user_can('manage_options')) {
        wp_send_json_error(
            array('message' => 'Droits insuffisants.'),
            403
        );
    }

    /**
     * 4) Validation/sanitation des entrées.
     * Ici, on choisit volontairement une option texte simple.
     * Si vous devez autoriser du HTML, utilisez wp_kses() avec une whitelist stricte.
     */
    $value = isset($_POST['value']) ? sanitize_text_field(wp_unslash($_POST['value'])) : '';

    if ($value === '') {
        wp_send_json_error(
            array('message' => 'Valeur vide.'),
            400
        );
    }

    /**
     * 5) Écriture en base.
     */
    update_option('bpcab_banner_text', $value, false);

    /**
     * 6) Réponse JSON propre.
     */
    wp_send_json_success(
        array('message' => 'Enregistré.')
    );
}

Créer et envoyer le nonce correctement

Le nonce doit être généré côté WordPress et envoyé au JavaScript. La méthode propre : wp_localize_script() (ou wp_add_inline_script()) après un wp_enqueue_script().

Exemple minimal (toujours dans le mu-plugin) : vous chargez un script sur le front, puis vous lui passez l’URL AJAX et le nonce.

<?php
add_action('wp_enqueue_scripts', function () {
    // Chargez votre script (exemple). Adaptez le chemin à votre thème/enfant.
    wp_enqueue_script(
        'bpcab-front',
        get_stylesheet_directory_uri() . '/assets/js/bpcab-front.js',
        array(),
        '1.0.0',
        true
    );

    // Données accessibles dans window.BPCAB
    wp_localize_script('bpcab-front', 'BPCAB', array(
        'ajaxUrl' => admin_url('admin-ajax.php'),
        'nonce'   => wp_create_nonce('bpcab_settings'),
    ));
});

Et côté JS (fichier assets/js/bpcab-front.js) :

async function bpcabSaveSetting(value) {
  const body = new URLSearchParams();
  body.set('action', 'bpcab_save_setting');
  body.set('nonce', window.BPCAB?.nonce || '');
  body.set('value', value);

  const res = await fetch(window.BPCAB?.ajaxUrl || '', {
    method: 'POST',
    credentials: 'same-origin',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
    body
  });

  const json = await res.json();
  if (!json.success) {
    throw new Error(json.data?.message || 'Erreur');
  }
  return json.data;
}

Pourquoi cette version est réellement plus sûre

  • Pas de nopriv : votre endpoint n’est pas une API publique.
  • Nonce : réduit fortement le risque CSRF (un tiers ne peut pas déclencher l’action depuis un autre site).
  • Capabilities : même si un compte est compromis (abonné), il ne peut pas toucher aux options globales.
  • Sanitization : vous évitez d’enregistrer des payloads dangereux.
  • Réponses JSON : plus simple à déboguer, moins de risques de “echo” accidentel qui casse la réponse.

Piège que je vois souvent : des gens utilisent un hook inadapté (init) pour enregistrer des actions AJAX, puis ajoutent des conditions qui ne s’exécutent pas en AJAX. Gardez l’enregistrement des actions avec add_action('wp_ajax_...') sans logique de contexte.

Sources utiles sur ces sujets :


Configuration serveur

La sécurité WordPress ne se joue pas uniquement dans l’admin. Deux réglages serveur simples évitent des compromissions très classiques : exécution de PHP dans uploads et fuite d’infos via headers.

.htaccess (Apache) : bloquer l’exécution PHP dans uploads

Si un attaquant arrive à déposer un fichier .php dans wp-content/uploads, il tentera de l’exécuter via le navigateur. Sur beaucoup d’hébergements Apache, vous pouvez bloquer ça.

Créez (ou éditez) : wp-content/uploads/.htaccess

# Bloque l'exécution de PHP dans uploads (Apache)
<FilesMatch ".(php|phtml|phar)$">
  Deny from all
</FilesMatch>

Si votre Apache est en 2.4+ (quasi tous en 2026), la forme moderne est :

# Apache 2.4+ : bloque PHP dans uploads
<FilesMatch ".(php|phtml|phar)$">
  Require all denied
</FilesMatch>

Sur Nginx, c’est dans la conf serveur (pas dans WordPress). Si vous êtes sur un hébergement managé, demandez au support de refuser l’exécution PHP dans /wp-content/uploads/.

wp-config.php : désactiver l’éditeur de fichiers

L’éditeur de fichiers dans l’admin (Apparence → Éditeur) n’est pas une faille en soi. Mais dès qu’un compte admin est compromis, c’est une autoroute pour injecter du code.

Ajoutez dans wp-config.php (au-dessus de “That’s all”) :

<?php
// Empêche l'édition de fichiers via l'admin (réduit l'impact d'un compte admin compromis)
define('DISALLOW_FILE_EDIT', true);

Si vous n’installez jamais de plugins/thèmes via l’admin (workflow Git/SFTP), vous pouvez aller plus loin :

<?php
// Empêche l'installation/mise à jour via l'admin (à n'activer que si vous gérez tout autrement)
define('DISALLOW_FILE_MODS', true);

Attention : DISALLOW_FILE_MODS bloque aussi les mises à jour (y compris sécurité). Je ne le recommande pas aux débutants.

Headers HTTP : réduire XSS, clickjacking, fuites

Sur beaucoup d’hébergements, vous pouvez définir des headers via Apache. Exemple (à mettre dans le .htaccess à la racine WordPress) :

# Headers de sécurité (Apache + mod_headers)
<IfModule mod_headers.c>
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>

Pour Content-Security-Policy (CSP), allez doucement : une CSP trop stricte casse souvent Divi 5, Elementor ou Avada (scripts inline, CDNs). Si vous voulez commencer, faites-le en mode rapport côté serveur, puis durcissez progressivement.

Référence PHP (versions supportées, sécurité) :


Vérifier si votre site est vulnérable

Vous n’avez pas besoin d’outils “hacker” pour faire un diagnostic sérieux. WP-CLI + quelques vérifications de fichiers et d’options suffisent déjà.

Audit rapide via WP-CLI

Connectez-vous en SSH, placez-vous dans le dossier WordPress, puis :

# Version core
wp core version

# Vérifie l'intégrité des fichiers WordPress (détecte des fichiers core modifiés)
wp core verify-checksums

# Liste des comptes admin
wp user list --role=administrator --fields=ID,user_login,user_email,display_name,registered

# Liste des plugins et statut
wp plugin list --fields=name,status,version,update

# Liste des thèmes
wp theme list --fields=name,status,version,update

Ce que vous cherchez :

  • des admins inconnus ;
  • des plugins désactivés mais toujours présents (surface d’attaque + fichiers potentiellement modifiés) ;
  • des plugins/thèmes avec update=available ;
  • wp core verify-checksums qui signale des fichiers modifiés (sur un site standard, c’est un gros signal).

Vérifier les emplacements typiques de backdoors

Sans tomber dans la chasse aux sorcières, j’inspecte presque toujours :

  • wp-content/uploads/ (présence de .php, .phtml, .phar) ;
  • wp-content/mu-plugins/ (un fichier inconnu chargé automatiquement) ;
  • wp-content/plugins/ (plugins “random”, dossiers au nom suspect) ;
  • les tâches planifiées (WP-Cron) qui relancent du code.

Commandes utiles :

# Cherche des fichiers PHP dans uploads (souvent anormal)
find wp-content/uploads -type f ( -name "*.php" -o -name "*.phtml" -o -name "*.phar" ) -print

# Liste des tâches WP-Cron
wp cron event list --fields=hook,next_run,recurrence

Lire les logs (le signal le plus fiable)

Si vous avez accès aux logs Apache/Nginx, cherchez :

  • beaucoup de requêtes vers /wp-login.php et /xmlrpc.php ;
  • des POST vers /wp-admin/admin-ajax.php avec des actions inconnues ;
  • des hits sur des chemins qui n’existent pas (scan automatisé) ;
  • des pics d’erreurs 500/502 (souvent du code injecté qui plante).

Tableau de diagnostic (symptômes courants)

Symptôme Cause probable Vérification Solution
Redirections vers un site externe JS injecté (XSS) ou code ajouté au thème Inspecter le HTML rendu, comparer fichiers du thème, vérifier plugins récents Nettoyer fichiers, supprimer plugin en cause, durcir entrées (wp_kses), headers
Nouvel admin inconnu Identifiants compromis / plugin vulnérable / endpoint AJAX non protégé wp user list --role=administrator + logs connexion Supprimer compte, reset mots de passe, 2FA, patch plugin, vérifier nonces/capabilities
CPU qui explose Spam, cron malveillant, brute force, malware Logs + wp cron event list + scan fichiers Bloquer IP, nettoyer cron, WAF/limitation login, réinstaller core/plugins propres
Emails “phishing” envoyés depuis le site Compte SMTP compromis ou script mail injecté Logs mail / plugin SMTP / fichiers inconnus Révoquer identifiants, nettoyer, limiter exécution PHP, durcir permissions
Impossible de mettre à jour Permissions fichiers incorrectes / PHP trop ancien Vérifier owner/permissions, vérifier version PHP Corriger permissions, passer en PHP 8.1+, réactiver mises à jour

Erreurs de sécurité fréquentes

Erreur Risque Solution
Garder des plugins/thèmes désactivés “au cas où” Fichiers vulnérables toujours exploitables Supprimez ce qui n’est pas utilisé. Sauvegardez un ZIP hors serveur si besoin.
Copier du code dans le mauvais endroit (thème parent, mauvais fichier) Perte à la mise à jour, comportement imprévisible Utilisez un thème enfant ou mieux : un plugin custom / mu-plugin.
Oublier une parenthèse ou un point-virgule dans un snippet Écran blanc (fatal error) et admin inaccessible Testez sur staging, activez logs PHP, gardez un accès SFTP pour corriger.
Utiliser un hook inadapté Contrôles de sécurité non exécutés (AJAX, REST, admin) AJAX : wp_ajax_*. Admin : admin_init. REST : rest_api_init.
Confusion entre actions et filtres Code jamais appelé, ou appelée au mauvais moment Action = “faire”. Filtre = “modifier une valeur et la retourner”.
Oublier nonce et capacités sur un formulaire/AJAX CSRF, élévation de privilèges wp_nonce_field() / check_admin_referer() / check_ajax_referer() + current_user_can().
Tester directement en production sans sauvegarde Site cassé ou données perdues Staging + sauvegarde + plan de rollback.
Cache non vidé (plugin, serveur, navigateur) Vous croyez qu’un correctif ne marche pas Videz cache plugin + cache serveur/CDN + navigateur.
Permaliens non régénérés après changement majeur 404, endpoints cassés, comportements bizarres Réglages → Permaliens → Enregistrer, ou wp rewrite flush.
Version PHP trop ancienne Failles connues + incompatibilités plugins récents Passez en PHP 8.1+ (idéalement 8.2/8.3 si compatible hébergeur).
Suivre un vieux tutoriel incompatible WordPress 6.9+ API obsolète, sécurité manquante Vérifiez sur developer.wordpress.org et privilégiez les patterns modernes.

Checklist de durcissement

Voici les 10 mesures essentielles (et actionnables) que je recommande à quasiment tous les débutants. Faites-les dans cet ordre, c’est pragmatique.

1) Activer les mises à jour automatiques (core + sécurité plugins)

Dans WordPress 6.9.4, les mises à jour automatiques sont stables et fiables pour la majorité des sites. Activez :

  • mises à jour automatiques du core (mineures au minimum) ;
  • auto-updates pour les plugins critiques (sécurité, cache, SEO si vous en dépendez).

Référence :

2) Supprimer ce qui ne sert pas (plugins, thèmes, comptes)

Supprimer > désactiver. Un plugin désactivé reste un dossier lisible et parfois exploitable si un fichier est directement accessible.

  • supprimez les thèmes non utilisés (gardez-en un de secours) ;
  • supprimez les plugins inactifs ;
  • supprimez les comptes utilisateurs inutiles.

3) Verrouiller les comptes : mots de passe + 2FA + emails

  • mots de passe uniques (gestionnaire recommandé) ;
  • 2FA (application TOTP) pour tous les admins ;
  • adresse email admin sécurisée (elle réinitialise vos mots de passe).

Si vous utilisez Divi 5 / Elementor / Avada : ces outils n’augmentent pas le risque par eux-mêmes, mais ils poussent à installer beaucoup d’add-ons. Chaque add-on est un risque potentiel. Le 2FA compense énormément.

4) Limiter les tentatives de connexion et protéger wp-login

Vous pouvez le faire via un plugin réputé (WAF/limiteur de login) ou via votre hébergeur (fail2ban, règle WAF). Sur hébergement managé, c’est souvent déjà en place.

Évitez les solutions “maison” qui modifient wp-login.php. J’ai vu trop de sites se verrouiller tout seuls après une mise à jour.

5) Désactiver XML-RPC si vous n’en avez pas besoin

xmlrpc.php est moins utilisé aujourd’hui. Si vous n’utilisez pas une app mobile ancienne ou des intégrations spécifiques, vous pouvez le bloquer au niveau serveur/WAF.

Référence :

6) Permissions de fichiers correctes (et propriétaire)

Règle simple (à adapter à votre hébergeur) :

  • dossiers : 755
  • fichiers : 644
  • wp-config.php : parfois 640 ou 600 selon serveur

Le vrai sujet, c’est l’owner (propriétaire). Si PHP tourne sous un user différent de celui qui possède les fichiers, vous vous retrouvez avec des permissions trop ouvertes “pour que ça marche”. Demandez à l’hébergeur la recommandation exacte.

7) Interdire l’édition de fichiers et réduire l’impact d’un admin compromis

Activez DISALLOW_FILE_EDIT (voir section serveur). C’est un petit changement, gros gain en incident.

8) Renouveler les clés de sécurité (AUTH_KEY, etc.) après incident ou doute

Les clés/“salts” signent les cookies de session. Si vous les changez, vous déconnectez tout le monde, ce qui est utile après un soupçon de vol de session.

Référence officielle :

9) Sauvegardes automatiques + test de restauration

Une sauvegarde non testée est une théorie. Faites :

  • sauvegarde quotidienne de la base ;
  • sauvegarde des fichiers (au moins hebdo) ;
  • stockage hors serveur (S3, Backblaze, Google Cloud, etc.) ;
  • test de restauration sur staging une fois.

10) Installer une surveillance minimale (logs + alertes)

Minimum viable :

  • alertes de nouveaux utilisateurs admin ;
  • alertes de modifications de fichiers (si votre hébergeur ou un plugin le fait proprement) ;
  • journal d’activité (qui a fait quoi) si vous êtes plusieurs.

Le piège : installer 5 plugins “sécurité” qui se chevauchent. Vous créez des conflits, des faux positifs, et parfois des trous (car vous désactivez des protections “qui gênent”). Un bon WAF + 2FA + updates suffit déjà à calmer 80% des attaques opportunistes.


Que faire si le site est déjà compromis ?

Quand un site est compromis, le mauvais réflexe est de “supprimer le malware” à la main et de s’arrêter là. Si l’entrée initiale existe encore (plugin vulnérable, mots de passe volés), vous serez re-compromis.

  1. Mettre le site en maintenance (ou au minimum bloquer l’admin) pour éviter que l’attaque continue.
  2. Faire une copie forensique : zip des fichiers + dump SQL. Ça sert si vous devez comprendre l’entrée, ou prouver ce qui s’est passé.
  3. Changer tous les mots de passe : WordPress (tous les utilisateurs), FTP/SFTP, base de données, panel hébergeur, SMTP, clés API.
  4. Vérifier les admins : supprimer les comptes inconnus, vérifier emails et dates d’inscription.
  5. Réinstaller proprement le core (sans toucher wp-content) :
    # Réinstalle WordPress core (sans effacer wp-content)
    wp core download --force
  6. Réinstaller plugins et thèmes depuis des sources propres :
    • supprimez le dossier du plugin, puis réinstallez depuis wordpress.org ou l’éditeur ;
    • évitez de “réparer” un plugin en place (vous gardez potentiellement un fichier backdoor).
  7. Inspecter wp-content/uploads et supprimer toute exécution PHP (voir règle .htaccess). Supprimez les fichiers suspects.
  8. Vérifier la base de données :
    • options anormales (scripts dans des options de thème) ;
    • contenus modifiés (liens cachés) ;
    • utilisateurs ajoutés.
  9. Renouveler les keys/salts dans wp-config.php pour invalider les sessions.
  10. Patch de l’entrée : mise à jour du plugin vulnérable, suppression d’un add-on, durcissement login, etc.
  11. Scanner et surveiller pendant 72h : logs, nouveaux fichiers, nouveaux admins.

Si vous êtes sur un site e-commerce ou avec données personnelles : traitez ça comme un incident de sécurité. Prévenez l’hébergeur, conservez les logs, et regardez vos obligations (RGPD, notification). Ne “nettoyez” pas en détruisant toutes les preuves si vous devez investiguer.


Conseils de maintenance et compatibilité

Compatibilité Divi 5, Elementor, Avada : où la sécurité dérape

Ces builders sont compatibles avec WordPress 6.9.4, mais la sécurité se dégrade souvent à cause des add-ons :

  • modules tiers qui ajoutent des endpoints AJAX sans nonce ;
  • widgets qui acceptent du HTML/JS “custom” et l’affichent à tous ;
  • import de templates provenant de sources douteuses.

Mes règles pratiques :

  • limitez les add-ons : gardez ceux qui sont maintenus et mis à jour ;
  • évitez d’autoriser du HTML non filtré à des rôles non-admin ;
  • pour du code custom, préférez un plugin custom et des shortcodes simples plutôt qu’un “snippet” collé partout.

Sécurité du code : les 4 réflexes

  • Validation : vérifier que la donnée reçue a le bon type/format.
  • Sanitization : nettoyer la donnée avant stockage (ex : sanitize_text_field()).
  • Échappement : échapper avant affichage (ex : esc_html(), esc_attr(), esc_url()).
  • Autorisation : vérifier les droits (current_user_can()) + nonce.

Références (très concrètes) :

Performance/SEO : sécurité et vitesse ne s’opposent pas

Un WAF, des headers, la désactivation d’édition de fichiers, et des mises à jour automatiques n’ont quasiment aucun impact performance. À l’inverse, un site infecté finit souvent avec :

  • des scripts injectés qui alourdissent les pages ;
  • des redirections qui détruisent le SEO ;
  • des blacklist (navigateurs, moteurs, hébergeurs).

Si vous mettez une CSP stricte, testez vos pages builder (Divi/Elementor/Avada) et vos formulaires. Commencez en “report-only” côté serveur si possible, puis durcissez.


Ressources


FAQ

Dois-je installer un plugin de sécurité si je suis débutant ?

Souvent oui, si vous choisissez un seul plugin sérieux (WAF/limitation login/alertes) et que vous le maintenez à jour. Évitez d’empiler 3–4 plugins “sécurité” qui font la même chose.

Les mises à jour automatiques peuvent-elles casser mon site ?

C’est rare, mais possible (surtout sur des sites très personnalisés). Le vrai filet de sécurité, ce sont des sauvegardes et un staging. Pour un blog simple, activer les auto-updates est généralement un gain net.

Est-ce que changer le préfixe de tables (wp_) suffit ?

Non. Ça peut réduire quelques attaques très anciennes, mais la majorité des compromissions modernes passent par des failles de plugins, du XSS, ou des identifiants volés.

Dois-je masquer la page de connexion ?

Ça peut réduire le bruit (bots), mais ce n’est pas une protection principale. Priorisez 2FA, limitation de tentatives, mots de passe uniques, et mises à jour.

Pourquoi supprimer un plugin désactivé, puisqu’il ne tourne pas ?

Parce que des fichiers peuvent rester accessibles directement via une URL, ou être utilisés comme point d’entrée si une vulnérabilité existe. En dépannage, j’ai vu des backdoors cachées dans des plugins “désactivés depuis des mois”.

Comment savoir si un snippet trouvé sur internet est dangereux ?

Signaux rouges : accès via wp_ajax_nopriv_* sans nonce, usage direct de $_POST/$_GET sans sanitation, absence de current_user_can(), et affichage de contenu non échappé.

Est-ce que Elementor/Divi/Avada sont “moins sécurisés” ?

Pas intrinsèquement. Le risque vient plutôt du nombre d’extensions ajoutées et du contenu custom (HTML/JS) qu’on finit par autoriser. Gardez vos builders et add-ons à jour, et limitez les modules tiers.

Que faire si j’ai un écran blanc après avoir ajouté du code ?

Connectez-vous en SFTP, supprimez/renommez le fichier modifié (ou le mu-plugin), puis réactivez progressivement. Pour éviter ça : testez sur staging et utilisez un éditeur avec vérification syntaxique.

WP-CLI est-il obligatoire ?

Non, mais il fait gagner un temps énorme pour auditer et réparer proprement. Sur un site compromis, c’est souvent plus fiable que de cliquer dans l’admin.

Dois-je bloquer l’exécution PHP dans uploads même si je n’ai jamais été hacké ?

Oui, si votre serveur le permet. C’est une défense simple contre une classe d’attaques très courante (upload + exécution).