[{"data":1,"prerenderedAt":211},["ShallowReactive",2],{"seo-verification":3,"blog-bricksforge-cve-2026-85097-wordpress-update-en":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-bricksforge-cve-2026-85097-wordpress-update-en",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":33,"intro":36,"sections":37,"ctaTitle":159,"ctaBody":160,"ctaButton":161,"ctaUrl":162,"relatedPosts":163},525,"bricksforge-cve-2026-85097-wordpress-update",{"fr":12,"en":10,"ar":13,"es":14},"bricksforge-cve-2026-85097-wordpress-mettre-a-jour","ثغرة-bricksforge-cve-2026-85097-ووردبريس-التحديث","bricksforge-cve-2026-85097-wordpress-actualizar","Bricksforge CVE-2026-85097: update and audit your WordPress fleet","Bricksforge 3.1.8.10 fixes CVE-2026-85097, an exploited unauthenticated upload. wp-cli inventory, dropped PHP files, access logs, secrets to rotate.",10,0,false,"2026-10-29T00:00:00+00:00","2026-10-29T15:45:55+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},8,"Security & Monitoring","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[29],{"id":23,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fbricksforge-cve-2026-85097-wordpress-mettre-a-jour-poster.svg",{"categorySlug":34,"appSlug":35},"cms-websites","wordpress","An unauthenticated upload flaw in the Bricksforge plugin, an add-on for the Bricks builder, was already being exploited before it went public. A fix exists, but updating is not enough: a patched site may already hold a PHP file dropped before the update. For an agency the difficulty is twofold: knowing which clients run the plugin, then proving none of them was visited. This guide gives the full procedure, from the wp-cli inventory to secret rotation, with Bricksforge as the worked example and a template to replay for the next flaw.",[38,42,80,83,105,108,111,132,136,139,150,153,156],{"type":39,"title":40,"body":41},"h2","The flaw in one paragraph, the rest is procedure","CVE-2026-85097 affects Bricksforge 3.1.8.9 and earlier; the fix is version 3.1.8.10. The Pro Forms module checks a file's MIME type on the first upload, but when the form is submitted it trusts the client-supplied `url` field in the `temporaryFileUploads` parameter. A GIF\u002FPHP polyglot file passes the check, then is referenced with a PHP destination URL: the server writes it there and runs it on the first request.\n\nOn severity, sources differ: critical, with a CVSS score of 9.8 according to SecurityWeek and 10.0 according to the Patchstack advisory. We do not pick one, as the response is the same. Patchstack saw the first exploitation on October 7, 2026, before disclosure (advisory of October 8), and SecurityWeek, in its October 12 article, cites about 6,000 sites running the plugin. Attacker IP lists are short-lived: they are in the Patchstack advisory, no need to copy them.",{"type":43,"title":44,"headers":45,"rows":49},"comparison","Reference table: where to look, what to look for",[46,47,48],"Where to look","What to look for","What it means",[50,54,58,62,66,70,73,76],[51,52,53],"Plugin version","Bricksforge 3.1.8.9 or earlier","Vulnerable: move to 3.1.8.10 or later",[55,56,57],"Plugin absent or deactivated","No line in the wp-cli inventory","No exposure through this plugin, record it anyway",[59,60,61],"`wp-content\u002Fuploads\u002Fbricksforge\u002Ftmp\u002F`","Any PHP file","Probable drop: treat the site as compromised",[63,64,65],"`wp-content\u002Fuploads\u002FYYYY\u002FMM\u002F`","`login_admin_*.php` files","Target named by Patchstack: treat the site as compromised",[67,68,69],"Access logs","POST to `\u002Fwp-json\u002Fbricksforge\u002Fv1\u002Fform_submit`","Attempt: cross-check with the state of the disk",[67,71,72],"`admin-ajax.php` with `bricksforge_form_submit` or `bricksforge_regenerate_nonce`","Attempt: the nonce is requested before the upload",[67,74,75],"Request to a PHP file under `uploads\u002F`","Probable execution: rotate secrets",[77,78,79],"WordPress accounts","Recent, unknown administrator","Possible persistence: consider a restore",{"type":39,"title":81,"body":82},"Why updating is not enough","Exploitation came before the fix. A site moved to 3.1.8.10 on October 20 may have received a file on the 8th, and that file survives the update: the patch closes the door, it does not remove what is already inside. This is the objection to settle before telling a client \"everything is fixed\". The right order is: patch or neutralise, then look for compromise (files, logs, accounts, secrets), then hand over dated proof.\n\nThere is a second, more mundane obstacle: without a central inventory, nobody knows which clients run the plugin. A Bricks site delivered two years ago and hosted by another provider appears in no alert. The inventory therefore comes first, and it serves every future plugin flaw.",{"type":84,"title":85,"steps":86},"steps","Inventory the fleet with wp-cli",[87,90,93,96,99,102],{"title":88,"body":89},"Test one site at a time","`cd \u002Fhome\u002Fclient\u002Fpublic_html`\n`wp plugin is-installed bricksforge && wp plugin get bricksforge --field=version`\n`wp plugin list --fields=name,version,update`\nThe first command answers through its exit code, the second prints the version, the third lists every plugin with its update status. The path is an example: adapt it to your host.",{"title":91,"body":92},"Find every site on a server","`find \u002Fhome -name wp-config.php -not -path '*\u002Fwp-content\u002F*'`\nEach `wp-config.php` points to an installation. The filter drops copies stored inside themes or backups; read the list through, a forgotten test subfolder counts too.",{"title":94,"body":95},"Loop over all installations","`find \u002Fhome -name wp-config.php -not -path '*\u002Fwp-content\u002F*' -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>\u002Fdev\u002Fnull)\"; done`\nEach line prints the folder then the version, or nothing if the plugin is absent. The `--skip-plugins --skip-themes` options avoid loading potentially booby-trapped code during the audit.",{"title":97,"body":98},"Choose the user carefully","Run wp-cli as the site's owner user, as in the loop above. `--allow-root` works, but it creates root-owned files in the site and runs the site's code with full rights: keep it for cases where nothing else is possible.",{"title":100,"body":101},"Capture the result in a table","One row per installation: client, host, path, version found, date and time of the check. Add a \"visited since October 7\" column to fill in at the next stage. This table becomes the centrepiece of the file you hand to clients.",{"title":103,"body":104},"Cover sites outside your server","For a site hosted elsewhere, ask for temporary access or an export of `wp plugin list --fields=name,version,update`. A site you cannot query stays in the table marked \"not verified\", not missing.",{"type":39,"title":106,"body":107},"Prioritise and set the look-back window","Handle first what is both exposed and exploited: a site with Bricksforge at 3.1.8.9 or lower, public Pro Forms forms, in production. Next come staging sites and working copies, then those where the plugin is installed but inactive. A dormant plugin deserves a decision: removing it is safer than letting it age.\n\nThe look-back window starts on October 7, 2026 at 21:47 UTC, the first signal published by Patchstack. Convert that time to the timezone of your logs before filtering. The key point: if your logs do not reach back to that date, the absence of a trace proves nothing. Note the date of the oldest line available, as it limits what you can state.",{"type":39,"title":109,"body":110},"Update, or neutralise in the meantime","When updating is possible, `wp plugin update bricksforge` is enough for an installation that receives releases normally; depending on the licence, the site may require going through its dashboard or the vendor's archive. Then check with `wp plugin get bricksforge --field=version`: the result must be 3.1.8.10 or later.\n\nWhen it is not yet possible, three temporary measures exist, none replacing the fix. Deactivating the plugin with `wp plugin deactivate bricksforge` cuts the route, at the cost of the site's forms: warn the client. Forbidding PHP execution in `uploads\u002F` removes the value of a dropped file: on nginx, `location ~* ^\u002Fwp-content\u002Fuploads\u002F.*\\.(php|php[0-9]|phtml|pht|phps)$ { deny all; }` placed before the general PHP block; on Apache, an `.htaccess` in `uploads\u002F` with `\u003CFilesMatch \"\\.(php|php[0-9]|phtml|pht|phps)$\"> Require all denied \u003C\u002FFilesMatch>`. Finally, rate limiting on `\u002Fwp-json\u002Fbricksforge\u002Fv1\u002Fform_submit` slows bursts, and Patchstack's RapidMitigate rule blocks the attack traffic for those who use that service. These measures reduce risk, they do not fix the flaw.",{"type":84,"title":112,"steps":113},"Hunt for dropped files and access traces",[114,117,120,123,126,129],{"title":115,"body":116},"Look for PHP files in uploads","`find wp-content\u002Fuploads -type f \\( -iname '*.php' -o -iname '*.php[0-9]' -o -iname '*.phtml' -o -iname '*.pht' -o -iname '*.phps' \\) -ls`\nA healthy `uploads\u002F` folder holds no executable PHP. A few-byte `index.php` that is just a comment is common and harmless; read any other file before judging it.",{"title":118,"body":119},"Aim at the targets named by Patchstack","`ls -la wp-content\u002Fuploads\u002Fbricksforge\u002Ftmp\u002F`\n`find wp-content\u002Fuploads -name 'login_admin_*.php' -ls`\n`find wp-content\u002Fuploads -type f -newermt '2026-10-07' -ls`\nThe first two commands target the locations and file name from the advisory; the third lists everything written to `uploads\u002F` since October 7, to catch a variant.",{"title":121,"body":122},"Sweep the nginx logs","`zgrep -h -i -E 'bricksforge\u002Fv1\u002Fform_submit|bricksforge_(form_submit|regenerate_nonce)' \u002Fvar\u002Flog\u002Fnginx\u002Faccess.log*`\n`zgrep` reads compressed and plain files alike: gzip rotation is therefore covered by the wildcard. Keep each line's date and compare it with the look-back window.",{"title":124,"body":125},"Sweep the Apache and cPanel logs","`zgrep -h -i -E 'bricksforge\u002Fv1\u002Fform_submit|bricksforge_(form_submit|regenerate_nonce)' \u002Fvar\u002Flog\u002Fapache2\u002F*access*.log* \u002Fvar\u002Flog\u002Fhttpd\u002F*access*log* \u002Fusr\u002Flocal\u002Fapache\u002Fdomlogs\u002F*`\nFolders vary: `\u002Fvar\u002Flog\u002Fapache2\u002F` on Debian and Ubuntu, `\u002Fvar\u002Flog\u002Fhttpd\u002F` on RHEL and AlmaLinux, `\u002Fusr\u002Flocal\u002Fapache\u002Fdomlogs\u002F` on a cPanel server. Missing paths produce a harmless error.",{"title":127,"body":128},"Look for access to dropped files","`zgrep -h -i -E 'login_admin_[^ ]*\\.php|\u002Fuploads\u002F[^ ]*\\.(php[0-9]?|phtml|pht)|%2e(php|phtml)' \u002Fvar\u002Flog\u002Fnginx\u002Faccess.log*`\nA request, especially a successful GET, to a PHP file under `uploads\u002F` means a file may have run. Case and encoding variants are covered here, in the logs, not on disk.",{"title":130,"body":131},"Count the sources and record","`zgrep -h 'POST \u002Fwp-admin\u002Fadmin-ajax.php' \u002Fvar\u002Flog\u002Fnginx\u002Faccess.log* | awk '{print $1}' | sort | uniq -c | sort -rn | head`\nThis command ranks addresses by number of POSTs to `admin-ajax.php`. Record the result, even if empty, with the oldest log date read.",{"type":133,"title":134,"body":135},"tip","What the logs do not show","The AJAX action often travels in the POST body, which the access log does not record: searching for `bricksforge_form_submit` may find nothing even though the call happened. In that case, look for an abnormal volume of POSTs to `admin-ajax.php` or to the REST route, and cross-check with the state of the disk. This guide describes administration tasks; it is provided as is, with no support from us.",{"type":39,"title":137,"body":138},"A file found: the site can no longer be considered healthy","A dropped file implies code execution on the server with the rights of the site's account. Deleting the file alone is not enough: it may have been used to create an account, read `wp-config.php` or plant a second door. Isolate the site, keep a copy of the file for analysis, then restore from a backup older than October 7, 2026 rather than cleaning by hand.\n\nAfter the restore, update Bricksforge before putting the site back online, otherwise the same request starts again. If no clean backup exists, rebuild from source code and the content export, and treat any database extraction as suspect.",{"type":140,"title":141,"items":142},"ul","Secrets and accounts to renew after a compromise",[143,144,145,146,147,148,149],"**Salts and keys in `wp-config.php`** — `wp config shuffle-salts` regenerates them and invalidates open sessions, including an intruder's.","**Database password** — change it on the MySQL or MariaDB server, then in `wp-config.php`, without waiting.","**API keys and tokens** — payment, transactional email, mapping, third-party services declared in the site or the database.","**SMTP credentials** — a mail account readable in the configuration quickly gets used for fraudulent sending.","**Administrator passwords** — `wp user reset-password \u003CID>` for each, and a unique password per person.","**Unknown WordPress accounts** — `wp user list --fields=ID,user_login,role,user_registered --orderby=user_registered --order=DESC` reveals recent creations.","**Persistence** — `wp cron event list`, the `wp-content\u002Fmu-plugins\u002F` folder and any plugins or themes that are not yours.",{"type":39,"title":151,"body":152},"The dated proof to hand to the client","A client who reads \"updated\" does not know what you checked. Hand over a one-page sheet per site: date and time of the audit, version before and after, results of the file searches, period covered by the logs with the date of the oldest line read, actions taken (restore, rotation, accounts removed) and what could not be checked. Including the limits protects as much as the results.\n\nThe sheet is also your protection if a compromise appears later: it dates what you knew and what you did. Keep the inventory table and the raw command outputs with the sheet.",{"type":39,"title":154,"body":155},"Replay the procedure for the next plugin flaw","Five steps, valid for any plugin. Inventory: plugin, version, site, client, host. Prioritise: exposed and exploited first. Set the look-back window from the first published signal. Neutralise or update, then look for files, access traces, accounts and secrets, in that order. Hand over the dated proof. Only the inventory command and the search patterns change, and the vendor or Patchstack advisory provides them.\n\nA fleet scattered across several hosts makes every step slow. A reseller account groups your sites under a single account, with one access point per client; SSH and wp-cli access depends on the plan, so check it first. You keep the client relationship, we run the infrastructure.",{"type":39,"title":157,"body":158},"Official documentation","Patchstack advisory on CVE-2026-85097: https:\u002F\u002Fpatchstack.com\u002Farticles\u002Fcritical-unauthenticated-arbitrary-file-upload-vulnerability-exploited-in-bricksforge-plugin\u002F\nSecurityWeek article: https:\u002F\u002Fwww.securityweek.com\u002Fbricksforge-wordpress-plugin-vulnerability-exploited-in-the-wild\u002F\n`wp plugin` commands: https:\u002F\u002Fdeveloper.wordpress.org\u002Fcli\u002Fcommands\u002Fplugin\u002F\n`wp config shuffle-salts` command: https:\u002F\u002Fdeveloper.wordpress.org\u002Fcli\u002Fcommands\u002Fconfig\u002Fshuffle-salts\u002F\nnginx `location` directive: https:\u002F\u002Fnginx.org\u002Fen\u002Fdocs\u002Fhttp\u002Fngx_http_core_module.html#location","A fleet of client sites, one audit loop","When client sites live with several hosts, every audit costs hours. With ServOrbit.com reseller hosting, one access point per client and a single interface let you group your clients' sites under a single interface, with your rates and your brand.","Discover the agency offer","\u002Fsolutions\u002Fagences",[164,180,196],{"id":165,"slug":166,"slugs":167,"title":171,"excerpt":172,"readTime":23,"views":18,"isPinned":19,"publishedAt":173,"updatedAt":174,"category":175,"categories":176,"featuredImage":30,"bgImage":31,"posterImage":178,"relatedSolution":179},373,"wordpress-cve-2026-87902-update-to-712-now",{"fr":168,"en":166,"ar":169,"es":170},"wordpress-cve-2026-87902-rce-mise-a-jour-7-1-2","ووردبريس-cve-2026-87902-ترقية-7-1-2","wordpress-cve-2026-87902-actualiza-a-712-urgente","WordPress CVE-2026-87902: Update to 7.1.2 Now","CVE-2026-87902 (CVSS 9.2) actively exploited since Sept. 22, 2026. Check your version, apply WordPress 7.1.2, and see why shared hosting extends exposure.","2026-09-24T00:00:00+00:00","2026-10-26T18:53:20+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[177],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fwordpress-cve-2026-87902-rce-mise-a-jour-7-1-2-poster.svg",{"categorySlug":34,"appSlug":35},{"id":181,"slug":182,"slugs":183,"title":187,"excerpt":188,"readTime":189,"views":18,"isPinned":19,"publishedAt":190,"updatedAt":191,"category":192,"categories":193,"featuredImage":30,"bgImage":31,"posterImage":195,"relatedSolution":30},508,"php-version-inventory-for-client-sites-an-agency-method",{"fr":184,"en":182,"ar":185,"es":186},"inventaire-versions-php-parc-sites-clients-agence","جرد-إصدارات-php-لمواقع-العملاء-منهج-للوكالات","inventario-de-versiones-php-de-sitios-cliente-metodo-de-agencia","PHP version inventory for client sites: an agency method","Build a register of the PHP version served by every client site across several hosts: access tiers, batch scripts, priority batches, client message, dated proof.",11,"2026-10-27T00:00:00+00:00","2026-10-27T23:58:39+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[194],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Finventaire-versions-php-parc-sites-clients-agence-poster.svg",{"id":197,"slug":198,"slugs":199,"title":203,"excerpt":204,"readTime":17,"views":18,"isPinned":19,"publishedAt":205,"updatedAt":206,"category":207,"categories":208,"featuredImage":30,"bgImage":31,"posterImage":210,"relatedSolution":30},521,"monthly-security-audit-checklist-client-vps-agency",{"fr":200,"en":198,"ar":201,"es":202},"checklist-audit-securite-mensuel-vps-clients-agence","قائمة-تدقيق-أمان-vps-شهرية-للعملاء-للوكالات","auditoria-seguridad-mensual-vps-clientes-agencia-checklist","Monthly client VPS security audit: a 45-minute checklist","Seven checks to run every month on a client VPS: updates, kernel, SSH accounts, ports, certificates, backups, logs. Includes a dated one-page report.","2026-10-28T00:00:00+00:00","2026-10-29T03:10:22+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[209],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fchecklist-audit-securite-mensuel-vps-clients-agence-poster.svg",1793289204603]