La faille en un paragraphe, le reste est de la procédure
CVE-2026-85097 touche Bricksforge 3.1.8.9 et les versions antérieures ; le correctif est la version 3.1.8.10. Le module Pro Forms contrôle le type MIME d'un fichier au premier envoi, mais fait confiance, à la soumission du formulaire, au champ url fourni par le client dans le paramètre temporaryFileUploads. Un fichier polyglotte GIF/PHP passe le contrôle, puis est référencé avec une URL de destination en PHP : le serveur l'écrit à cet endroit et l'exécute à la première requête.
Sur la gravité, les sources divergent : critique, avec un score CVSS de 9,8 selon SecurityWeek et de 10,0 selon l'avis de Patchstack. Nous ne tranchons pas, la conduite à tenir est la même. Patchstack a observé les premières exploitations le 7 octobre 2026, avant la divulgation (avis du 8 octobre), et SecurityWeek, dans son article du 12 octobre, cite environ 6 000 sites équipés du plugin. Les listes d'adresses IP attaquantes sont éphémères : elles figurent dans l'avis de Patchstack, inutile de les recopier.
Tableau de référence : où regarder, quoi chercher
Faites défiler le tableau
| Où regarder | Quoi chercher | Ce que cela indique |
|---|---|---|
| Version du plugin | Bricksforge 3.1.8.9 ou antérieure | Vulnérable : passer en 3.1.8.10 ou plus récent |
| Plugin absent ou désactivé | Aucune ligne dans l'inventaire wp-cli | Pas d'exposition par ce plugin, à consigner quand même |
| `wp-content/uploads/bricksforge/tmp/` | Tout fichier PHP | Dépôt probable : site à traiter comme compromis |
| `wp-content/uploads/AAAA/MM/` | Fichiers `login_admin_*.php` | Cible citée par Patchstack : site à traiter comme compromis |
| Journaux d'accès | POST sur `/wp-json/bricksforge/v1/form_submit` | Tentative : à croiser avec l'état du disque |
| Journaux d'accès | `admin-ajax.php` avec `bricksforge_form_submit` ou `bricksforge_regenerate_nonce` | Tentative : le nonce est demandé avant l'envoi |
| Journaux d'accès | Requête vers un fichier PHP sous `uploads/` | Exécution probable : rotation des secrets |
| Comptes WordPress | Administrateur récent et inconnu | Persistance possible : restauration à envisager |
Pourquoi mettre à jour ne suffit pas
L'exploitation a précédé le correctif. Un site passé en 3.1.8.10 le 20 octobre peut avoir reçu un fichier le 8, et ce fichier survit à la mise à jour : le patch ferme la porte, il ne retire pas ce qui est déjà entré. C'est l'objection à traiter avant d'écrire au client « tout est corrigé ». Le bon ordre est donc : patcher ou neutraliser, puis chercher la compromission (fichiers, journaux, comptes, secrets), puis remettre une preuve datée.
Il y a un second obstacle, plus banal : sans inventaire central, personne ne sait quels clients embarquent le plugin. Un site Bricks livré il y a deux ans, hébergé chez un autre prestataire, n'apparaît dans aucune alerte. L'inventaire vient donc en premier, et il vaut pour toutes les failles de plugin à venir.
Inventorier le parc avec wp-cli
Tester un site à la fois
cd /home/client/public_htmlwp plugin is-installed bricksforge && wp plugin get bricksforge --field=versionwp plugin list --fields=name,version,update
La première commande répond par son code de sortie, la deuxième affiche la version, la troisième liste tous les plugins avec leur état de mise à jour. Le chemin est un exemple : adaptez-le à votre hébergeur.Trouver tous les sites d'un serveur
find /home -name wp-config.php -not -path '*/wp-content/*'
Chaquewp-config.phpdésigne une installation. Le filtre écarte les copies rangées dans les thèmes ou les sauvegardes ; relisez la liste, un sous-dossier de test oublié compte aussi.Boucler sur toutes les installations
find /home -name wp-config.php -not -path '*/wp-content/*' -print0 | while IFS= read -r -d '' f; do d=$(dirname "$f"); echo "$d $(sudo -u "$(stat -c %U "$d")" wp --path="$d" --skip-plugins --skip-themes plugin get bricksforge --field=version 2>/dev/null)"; done
Chaque ligne affiche le dossier puis la version, ou rien si le plugin est absent. L'option--skip-plugins --skip-themesévite de charger du code potentiellement piégé pendant l'audit.Choisir l'utilisateur avec soin
Lancez wp-cli sous l'utilisateur propriétaire du site, comme dans la boucle ci-dessus.
--allow-rootfonctionne, mais crée des fichiers appartenant à root dans le site et exécute le code du site avec les pleins droits : réservez-le à un cas où rien d'autre n'est possible.Capturer le résultat dans un tableau
Une ligne par installation : client, hébergeur, chemin, version relevée, date et heure du relevé. Ajoutez une colonne « visité depuis le 7 octobre » que vous remplirez à l'étape suivante. Ce tableau devient la pièce centrale du dossier remis aux clients.
Compléter pour les sites hors de votre serveur
Pour un site hébergé ailleurs, demandez un accès temporaire ou un export de
wp plugin list --fields=name,version,update. Un site que vous ne pouvez pas interroger reste dans le tableau avec la mention « non vérifié », pas absent.
Prioriser et fixer la fenêtre de rétroaudit
Traitez d'abord ce qui est à la fois exposé et exploité : un site avec Bricksforge en 3.1.8.9 ou moins, formulaires Pro Forms publics, en production. Viennent ensuite les sites de recette et les copies de travail, puis ceux où le plugin est installé sans être actif. Un plugin dormant mérite une décision : le supprimer reste plus sûr que le laisser vieillir.
La fenêtre de rétroaudit commence le 7 octobre 2026 à 21:47 UTC, premier signal publié par Patchstack. Convertissez cette heure dans le fuseau de vos journaux avant de filtrer. Le point essentiel : si vos journaux ne remontent pas jusqu'à cette date, l'absence de trace ne prouve rien. Notez la date de la plus ancienne ligne disponible, elle limite ce que vous pouvez affirmer.
Mettre à jour, ou neutraliser en attendant
Quand la mise à jour est possible, wp plugin update bricksforge suffit pour une installation qui reçoit les versions normalement ; selon la licence, le site peut demander de passer par son tableau de bord ou par l'archive de l'éditeur. Vérifiez ensuite avec wp plugin get bricksforge --field=version : le résultat doit être 3.1.8.10 ou plus récent.
Quand elle ne l'est pas encore, trois parades provisoires existent, aucune ne remplace le correctif. Désactiver le plugin avec wp plugin deactivate bricksforge coupe la route, au prix des formulaires du site : prévenez le client. Interdire l'exécution de PHP dans uploads/ retire sa valeur à un fichier déposé : sous nginx, location ~* ^/wp-content/uploads/.*\.(php|php[0-9]|phtml|pht|phps)$ { deny all; } placé avant le bloc PHP général ; sous Apache, un .htaccess dans uploads/ avec <FilesMatch "\.(php|php[0-9]|phtml|pht|phps)$"> Require all denied </FilesMatch>. Enfin, une limitation de débit sur /wp-json/bricksforge/v1/form_submit ralentit les rafales, et la règle RapidMitigate de Patchstack bloque le trafic d'attaque pour qui utilise ce service. Ces mesures réduisent le risque, elles ne corrigent pas la faille.
Chasser les fichiers déposés et les traces d'accès
Chercher les fichiers PHP dans uploads
find wp-content/uploads -type f \( -iname '*.php' -o -iname '*.php[0-9]' -o -iname '*.phtml' -o -iname '*.pht' -o -iname '*.phps' \) -ls
Un dossieruploads/sain ne contient pas de PHP exécutable. Unindex.phpde quelques octets, simple commentaire, est courant et sans danger ; tout autre fichier se lit avant d'être jugé.Viser les cibles citées par Patchstack
ls -la wp-content/uploads/bricksforge/tmp/find wp-content/uploads -name 'login_admin_*.php' -lsfind wp-content/uploads -type f -newermt '2026-10-07' -ls
Les deux premières commandes visent les emplacements et le nom de fichier de l'avis ; la troisième liste tout ce qui a été écrit dansuploads/depuis le 7 octobre, pour repérer une variante.Balayer les journaux nginx
zgrep -h -i -E 'bricksforge/v1/form_submit|bricksforge_(form_submit|regenerate_nonce)' /var/log/nginx/access.log*zgreplit les fichiers compressés comme les fichiers en clair : la rotation gzip est donc incluse par le joker. Gardez la date de chaque ligne et comparez-la à la fenêtre de rétroaudit.Balayer les journaux Apache et cPanel
zgrep -h -i -E 'bricksforge/v1/form_submit|bricksforge_(form_submit|regenerate_nonce)' /var/log/apache2/*access*.log* /var/log/httpd/*access*log* /usr/local/apache/domlogs/*
Les dossiers varient :/var/log/apache2/sous Debian et Ubuntu,/var/log/httpd/sous RHEL et AlmaLinux,/usr/local/apache/domlogs/sur un serveur cPanel. Les chemins absents produisent une erreur sans gravité.Chercher l'accès aux fichiers déposés
zgrep -h -i -E 'login_admin_[^ ]*\.php|/uploads/[^ ]*\.(php[0-9]?|phtml|pht)|%2e(php|phtml)' /var/log/nginx/access.log*
Une requête, surtout un GET réussi, vers un fichier PHP sousuploads/signifie qu'un fichier a pu s'exécuter. Les variantes de casse et d'encodage se couvrent ici, dans les journaux, pas sur le disque.Compter les sources et consigner
zgrep -h 'POST /wp-admin/admin-ajax.php' /var/log/nginx/access.log* | awk '{print $1}' | sort | uniq -c | sort -rn | head
Cette commande classe les adresses par nombre de POST versadmin-ajax.php. Consignez le résultat, même vide, avec la plus ancienne date de journal lue.
Ce que les journaux ne montrent pas
L'action AJAX voyage souvent dans le corps du POST, que le journal d'accès n'enregistre pas : la recherche de bricksforge_form_submit peut alors ne rien trouver alors que l'appel a eu lieu. Dans ce cas, repérez un volume anormal de POST vers admin-ajax.php ou vers la route REST, et croisez-le avec l'état du disque. Ce guide décrit des gestes d'administration ; il est fourni tel quel, sans prise en charge de notre part.
Un fichier trouvé : le site n'est plus à considérer comme sain
La présence d'un fichier déposé implique une exécution de code côté serveur avec les droits du compte du site. Supprimer le fichier seul est insuffisant : il a pu servir à créer un compte, à lire wp-config.php ou à poser une seconde porte. Isolez le site, conservez une copie du fichier pour analyse, puis restaurez depuis une sauvegarde antérieure au 7 octobre 2026 plutôt que de nettoyer à la main.
Après la restauration, mettez Bricksforge à jour avant de remettre le site en ligne, sans quoi la même requête recommence. Si aucune sauvegarde saine n'existe, reconstruisez à partir du code source et de l'export du contenu, et traitez toute extraction de la base comme suspecte.
Secrets et comptes à renouveler après une compromission
- Sels et clés de
wp-config.php—wp config shuffle-saltsles régénère et invalide les sessions ouvertes, y compris celle d'un intrus. - Mot de passe de la base de données — changez-le côté serveur MySQL ou MariaDB, puis dans
wp-config.php, sans attendre. - Clés API et jetons — paiement, messagerie transactionnelle, cartographie, services tiers déclarés dans le site ou dans la base.
- Identifiants SMTP — un compte de messagerie lisible dans la configuration sert vite à de l'envoi frauduleux.
- Mots de passe des administrateurs —
wp user reset-password <ID>pour chacun, et un mot de passe unique par personne. - Comptes WordPress inconnus —
wp user list --fields=ID,user_login,role,user_registered --orderby=user_registered --order=DESCrévèle les créations récentes. - Persistances —
wp cron event list, le dossierwp-content/mu-plugins/et les plugins ou thèmes qui ne sont pas les vôtres.
La preuve datée à remettre au client
Un client qui lit « mis à jour » ne sait pas ce que vous avez vérifié. Remettez une fiche d'une page par site : date et heure de l'audit, version avant et après, résultat des recherches de fichiers, période couverte par les journaux avec la date de la plus ancienne ligne lue, actions menées (restauration, rotation, comptes supprimés) et ce qui n'a pas pu être contrôlé. Inclure les limites protège autant que les résultats.
Cette fiche est aussi votre protection si une compromission apparaît plus tard : elle date ce que vous saviez et ce que vous avez fait. Conservez le tableau d'inventaire et les sorties brutes des commandes avec la fiche.
Rejouer la procédure pour la prochaine faille de plugin
Cinq temps, valables pour n'importe quel plugin. Inventorier : plugin, version, site, client, hébergeur. Prioriser : exposé et exploité d'abord. Fixer la fenêtre de rétroaudit à partir du premier signal publié. Neutraliser ou mettre à jour, puis chercher fichiers, traces d'accès, comptes et secrets, dans cet ordre. Remettre la preuve datée. Seuls changent la commande d'inventaire et les motifs de recherche, que l'avis de l'éditeur ou de Patchstack donne.
Un parc éparpillé chez plusieurs hébergeurs rend chaque étape lente. Le compte revendeur regroupe vos sites sur un seul compte, avec un point d'accès par client ; l'accès SSH et wp-cli dépend du plan, vérifiez-le avant. Vous gardez la relation client, nous tenons l'infrastructure.
La documentation officielle
Avis de Patchstack sur CVE-2026-85097 : https://patchstack.com/articles/critical-unauthenticated-arbitrary-file-upload-vulnerability-exploited-in-bricksforge-plugin/
Article de SecurityWeek : https://www.securityweek.com/bricksforge-wordpress-plugin-vulnerability-exploited-in-the-wild/
Commandes wp plugin : https://developer.wordpress.org/cli/commands/plugin/
Commande wp config shuffle-salts : https://developer.wordpress.org/cli/commands/config/shuffle-salts/
Directive nginx location : https://nginx.org/en/docs/http/ngx_http_core_module.html#location