Comment garantir qu’un champ jamais destiné au public ne se retrouve jamais, par accident, exposé sur le site ? C’est la question posée par un cabinet médical qui souhaitait ajouter un champ « allergie connue » sur la fiche de chaque patient enregistrée comme un article personnalisé, sans jamais laisser transparaître cette information côté visiteur, ni même via l’API REST de WordPress.
Le risque n’est pas toujours celui qu’on imagine : le vrai danger, sur ce type de projet, ne vient presque jamais du thème public, mais de l’API REST activée par défaut sur tous les types de contenu enregistrés dans WordPress. Un champ personnalisé mal configuré peut se retrouver accessible via une simple requête vers /wp-json/wp/v2/patients/123, même si aucun gabarit de thème ne l’affiche jamais.
Poser le champ avec register_meta
Pour un champ sensible, la fonction register_meta() est le point de contrôle central. Son paramètre show_in_rest, laissé à false, empêche la donnée d’apparaître dans les réponses de l’API REST, y compris pour un utilisateur authentifié qui n’a pas les droits adéquats.
add_action( 'init', 'cabinet_register_champ_allergie' );
function cabinet_register_champ_allergie() {
register_post_meta( 'patient', 'allergie_connue', array(
'type' => 'string',
'single' => true,
'show_in_rest' => false,
'auth_callback' => function() {
return current_user_can( 'edit_patients' );
},
) );
}
Le rappel important : par défaut, un champ personnalisé enregistré sans précision reste invisible côté REST, mais il vaut mieux le déclarer explicitement plutôt que de compter sur un comportement implicite qui pourrait changer avec une mise à jour de cœur ou une extension tierce mal écrite.
Afficher le champ uniquement dans une metabox restreinte
La saisie du champ passe par une metabox classique, ajoutée via add_meta_box(), mais avec une vérification de capacité à l’affichage comme à l’enregistrement. Le rôle personnalisé « praticien » du cabinet dispose d’une capacité edit_patients dédiée, distincte des capacités par défaut d’un éditeur WordPress.
function cabinet_metabox_allergie() {
add_meta_box(
'allergie_connue',
'Allergie connue (confidentiel)',
'cabinet_render_metabox_allergie',
'patient',
'side'
);
}
add_action( 'add_meta_boxes', 'cabinet_metabox_allergie' );
function cabinet_render_metabox_allergie( $post ) {
if ( ! current_user_can( 'edit_patients' ) ) {
echo '<p>Accès restreint.</p>';
return;
}
$valeur = get_post_meta( $post->ID, 'allergie_connue', true );
wp_nonce_field( 'cabinet_allergie_nonce', 'cabinet_allergie_nonce_champ' );
echo '<textarea name="allergie_connue" rows="3" style="width:100%">' . esc_textarea( $valeur ) . '</textarea>';
}

Ce que ce champ ne règle pas
Ajouter un champ personnalisé bien cloisonné ne remplace pas une politique de sécurité des données de santé. Le chiffrement des données sensibles dans la base MySQL, le contrôle des sauvegardes, ou la conformité au Référentiel des Organismes Traitant des Données de Santé restent des sujets à part entière, hors du périmètre d’un simple champ personnalisé.
- Un champ non exposé en REST reste lisible par quiconque a un accès direct à la base de données, sans chiffrement applicatif.
- La capacité personnalisée
edit_patientsdoit être attribuée avec soin, idéalement via un rôle dédié plutôt qu’en modifiant les capacités du rôle éditeur natif. - Les journaux d’activité (qui a consulté quelle fiche) sont un sujet distinct, à traiter avec une extension d’audit si le cabinet en a besoin.
Vérifier qu’aucune fuite ne subsiste
Avant de considérer le champ comme sécurisé, il faut tester la requête REST correspondante avec un compte non autorisé, et confirmer que la clé allergie_connue n’apparaît nulle part dans la réponse JSON, y compris dans les champs meta génériques si une extension tierce les expose globalement.
| Vérification | Résultat attendu |
|---|---|
| Requête REST anonyme sur /wp-json/wp/v2/patients/123 | Champ absent de la réponse |
| Affichage front du gabarit single-patient.php | Aucune référence au champ |
| Export CSV éventuel de la fiche patient | Champ exclu ou masqué selon le rôle exportateur |
Notre verdict
Pour un champ sensible isolé, register_post_meta() avec show_in_rest désactivé et une metabox contrôlée par capacité suffisent largement, sans surcharger le projet d’une extension de champs personnalisés généraliste. Le vrai travail de fond, sur ce type de site, reste la question du chiffrement et de la conformité réglementaire globale, qui dépasse largement la portée d’un simple champ ajouté à une fiche.