D’après la documentation officielle sur les capacités WordPress, disponible sur developer.wordpress.org, le système de rôles et permissions distingue une trentaine de capacités par défaut, un nombre suffisant pour dérouter un développeur qui découvre l’écosystème. Encadrer une recrue junior sur les réflexes de sécurité ne consiste pas à lui faire lire cette liste en une session, mais à construire une progression où chaque notion s’appuie sur du code réellement écrit, relu, et corrigé.
Sur l’encadrement d’un développeur junior arrivé sur un projet de refonte pour une PME du secteur du bâtiment, la progression suivante a été testée sur six semaines, en alternant code réel sur le projet et revues ciblées. Elle n’a rien d’universel, mais elle a permis d’éviter l’écueil classique d’une formation théorique déconnectée du travail quotidien.
Semaine 1-2 : l’échappement systématique des sorties
Le premier réflexe à ancrer, avant tout autre sujet, concerne l’échappement des données à l’affichage : esc_html(), esc_attr(), esc_url(). La méthode qui a fonctionné consistait à faire relire au junior du code déjà existant sur le projet, en lui demandant d’identifier chaque endroit où une donnée dynamique s’affiche sans échappement, plutôt que de partir d’exercices artificiels déconnectés du code réel.
Un exercice concret : reprendre un template de fiche produit et faire lister, ligne par ligne, quelle fonction d’échappement s’applique à quel contexte (URL, attribut HTML, texte brut). Cette étape seule a permis de corriger trois oublis réels sur le projet, ce qui a immédiatement donné du sens à l’exercice.
Semaine 3 : capacités et vérifications de permission
Une fois l’échappement acquis comme réflexe, la notion de current_user_can() et de vérification systématique avant toute action sensible (suppression, modification de contenu d’un autre auteur, accès à un réglage) devient la deuxième brique. Le junior a travaillé sur l’ajout d’une fonctionnalité d’export de données clients, avec pour consigne explicite de justifier, pour chaque route ajoutée, la capacité vérifiée et pourquoi.

Cette étape a aussi permis d’aborder un piège fréquent chez les débutants : vérifier is_admin() en pensant contrôler un accès, alors que cette fonction indique seulement si la requête a lieu côté administration, sans rien dire des droits de l’utilisateur connecté.
Semaine 4 : nonces et CSRF
Le sujet des nonces arrive naturellement après les capacités, puisque les deux se combinent systématiquement sur une action sensible. La consigne donnée : pour chaque formulaire d’administration ajouté au projet, vérifier la présence de wp_nonce_field() à la génération et de wp_verify_nonce() au traitement, et expliquer ce qui se passerait concrètement si l’un des deux manquait.
- Formulaire de suppression d’un enregistrement : nonce + capacité vérifiés ensemble
- Action déclenchée par un lien admin : nonce ajouté à l’URL via
wp_nonce_url() - Requête AJAX authentifiée : nonce transmis via
wp_localize_script()puis vérifié côté serveur
Semaine 5 : requêtes SQL et wpdb::prepare
Le sujet des injections SQL arrive volontairement après les nonces plutôt qu’en premier : sur ce projet particulier, aucune requête SQL directe n’était nécessaire avant cette étape, l’essentiel des accès aux données passant par WP_Query. Introduire $wpdb->prepare() au moment où une requête personnalisée devient réellement nécessaire — ici, pour une recherche multi-critères sur les commandes — donne plus de sens que de l’enseigner de façon abstraite.
Un exercice de relecture ciblé
// Version à corriger soumise au junior
$resultats = $wpdb->get_results(
"SELECT * FROM {$wpdb->prefix}commandes WHERE statut = '$statut'"
);
La correction attendue, avec $wpdb->prepare() et des marqueurs, a servi de base à une discussion sur pourquoi la concaténation directe reste dangereuse même quand la valeur semble provenir d’une source « interne » comme un menu déroulant.
Semaine 6 : capacités personnalisées et rôles sur mesure
La dernière étape, plus avancée, aborde la création d’une capacité personnalisée via add_cap() pour un rôle métier spécifique — dans ce cas, un rôle « gestionnaire de devis » distinct des rôles par défaut. Cette étape suppose les précédentes acquises : elle combine capacités, vérifications de permission et compréhension du modèle de rôles, et n’a de sens que si le junior maîtrise déjà les bases.
Un développeur junior qui comprend pourquoi une vérification est nécessaire la reproduit sans qu’on le lui rappelle ; un développeur qui l’applique par consigne l’oublie à la première fonctionnalité pressée.
Pour aller plus loin
Cette progression reste indicative et dépend fortement du projet sur lequel la recrue est encadrée : un projet e-commerce mettra l’accent plus tôt sur les webhooks et les paiements, un projet éditorial insistera davantage sur le filtrage du contenu riche. L’invariant qui a fonctionné sur plusieurs encadrements reste le même : faire relire et corriger du code réel, projet par projet, plutôt que dérouler un programme théorique identique quel que soit le contexte.