Recherche de 34zY / Hamza Terir sur un plugin WordPress public (ElementsKit Lite ≤ 3.7.6). Produit tiers nommé car public et corrigé en amont ; les sites clients où il a été observé sont anonymisés. PoC (détection de version + vérification du bypass) développé from scratch.
Contexte
ElementsKit Lite, plugin WordPress très répandu, expose une route REST pour l’inscription à une liste Mailchimp :
/wp-json/elementskit/v1/widget/mailchimp/subscribe
Comment je l’ai trouvée
En énumérant les routes REST du plugin, j’ai testé l’endpoint subscribe sans aucun header d’authentification :
POST /wp-json/elementskit/v1/widget/mailchimp/subscribe
{"email": "test@example.tld", "list_id": "canary"}
Réponse HTTP 200 (attendu : 401). J’ai confirmé le même comportement via la variante de routage /?rest_route=/elementskit/v1/widget/mailchimp/subscribe (indépendant des permaliens), puis vérifié l’absence de nonce CSRF. Contrôle négatif : /wp-json/wp/v2/users renvoie bien 401, prouvant que le défaut est spécifique au plugin et non une mauvaise config globale.
Validation technique
La découverte de route peut rester non destructive :
curl --fail-with-body --max-time 5 \
'https://AUTHORIZED_HOST/wp-json/' \
| jq '.routes | keys[] | select(test("elementskit"; "i"))'
Pour une route qui modifie un état, la vérification attendue porte sur permission_callback, l’authentification et le nonce avant tout traitement métier :
def allow_mutation(*, authenticated: bool, nonce_ok: bool) -> None:
if not authenticated or not nonce_ok:
raise PermissionError("authenticated nonce required")
Le retest utilise uniquement une liste de diffusion de test et un identifiant canary; aucune adresse réelle n’est injectée.
La faille
CWE-862 (Missing Authorization) : la route REST mutant un état n’enregistre pas de permission_callback ni de contrôle de nonce. N’importe quel tiers non authentifié peut POSTer des données. Corrigé côté éditeur en ≥ 3.7.9.
Impact
- Injection non authentifiée d’abonnés (spam / pollution de la liste).
- Abus automatisé à grande échelle (pas de rate limit ni de nonce).
- Intégrité compromise sur la liste de diffusion ; pas de lecture de données ni de RCE identifiée.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N = 7.5 (High).
Remédiation
- Exiger un nonce REST valide (
X-WP-Nonce) sur toute route mutant un état, y compris celles des plugins tiers. - Mettre à jour ElementsKit Lite en ≥ 3.7.9.
- Rate-limiting sur les endpoints publics d’inscription.
- Auditer toutes les routes REST personnalisées pour un
permission_callbackmanquant.
CWE-862 (Missing Authorization).