Changelog#
Versions are listed newest first. The version of an install is the Version header of bb-migrate.php and the
BB_MIGRATE_VERSION constant; both sites of a transfer should run the same one.
0.2.2 (2026-11-05)#
A security review of the push and pull paths. "Accept push" remains administrator-level access by design, and is no longer a route to code execution without "Allow code files". See Security.
Security#
- Strict SQL allow-list. SQL received from another site must be one of the statement forms the exporter emits:
DROP TABLE IF EXISTS,CREATE TABLE … (andINSERT INTO … VALUESon_bbmig_temp tables, plus the dump's session header lines. Statements are checked with every quoted literal blanked. This replaces a check on the statement's first keyword, which versioned comments,INSERT … SELECT,CREATE … SELECT,ALTER … RENAMEandSETon global variables could pass. The list now applies to pulled dumps as well as pushed chunks. - Snippet option validation. A Custom CSS & JS snippet's
optionsmust describe a css, js or html snippet with a plain preprocessor ID, in packages, meta writes and the snippets action. Before,language=phpproduced a PHP file under uploads. - Uploads rule. The uploads scope refuses an executable extension anywhere in a file name,
.htaccess,.user.ini,web.config,php.ini, and all dotfiles. - Path containment. Every read, write and delete checks the resolved path against the resolved scope root.
- No object instantiation on import. Packaged meta is unserialized with
allowed_classes => false. Attachment paths and size file names in a package must be valid upload paths. - The receiver keeps its own key and switches.
bb_migrate_settingsis restored after every import whatever the sender asks, andactive_pluginsis kept on a push unless "Allow code files" is on. Options namedbb_migrate_…are left out of every export, backup and push. - Backup names withheld. The pre-push backup's file name is no longer returned to the pushing site.
- The mu-plugin verifies the signature, on its own route only. The compatibility mu-plugin (version 3) checks the
HMAC itself before it disables anything, and matches only the plugin's REST path or
rest_routevalue instead of any URL containingbb-migrate/v1. - File replay markers. Replay protection uses one marker file per signature, created exclusively, in
uploads/bb-migrate/nonces/, instead of transients. .devis not local. Hosts under.devno longer count as local sites, so overwriting their database asks for the host name or--yes.- The plugin's own folder is not a scope.
plugin:bb-migrateis "Unknown scope" on both sides. New versions are installed by zip upload. - Client. Requests follow no redirects, plain
http://connections are accepted only to local-looking hosts, and private and loopback targets are refused unless the sending site is local. - Handshake and pulls list and export only the site's prefixed tables.
- Admin screen. Strings supplied by a remote are escaped before rendering. Finished and failed jobs are deleted at once; the stale-job cleanup now matches the right option prefix.
Changed#
--yesconfirmations.files push --delete,site activate,site deactivate,pages push --on-exists=updateandmeta pushask for confirmation on the command line unless--yes.
Added and fixed after the review (2026-11-06)#
- Client retries on idempotent routes. The handshake, file routes, export routes, package listing and export, and backup steps are tried up to three times on a transport failure or a non-JSON 5xx or 429 reply. Imports and site actions are never retried.
- Snippet URL-rules index rebuild. Regenerating snippets also rebuilds the
custom-css-js-urlsoption, so a pushed snippet with "where on site" rules prints without being saved by hand on the destination. - Summary table fix. The
pagesresult table no longer fails on rows without a URL (skipped and matched posts).
0.2.1 (2026-11)#
Fixes from the first deployment to a staging server.
- A file push stops on the first file the receiver could not write and names it. 0.2.0 reported success when the receiver's folder was not writable by PHP and nothing had been written.
- Files written by a push are left at mode
664and new folders at775, so an SFTP account in the web server's group can still edit them.
0.2.0 (2026-11-04)#
File sync by path, pruning, and the remote steps of a deploy.
- Path-scoped file sync.
--pathsand--paths-fileconfine a sync to folders, files or globs inside the scope, so one file or folder travels instead of the whole tree. - Pruning.
--deleteremoves files on the destination that the source no longer has: always available for theme and plugin scopes, for uploads only when the sync is confined to paths. The dry run lists copies and deletions. New routefiles-delete. --purgepurges the destination's cache after a sync.- Remote site actions.
wp bb-migrate site: list, activate and deactivate plugins; show, set and copy BB Cache settings; purge; regenerate Custom CSS & JS snippet files.wp bb-migrate meta push: write single meta values on a remote post. New routessite-plugins,site-cache,site-snippets,site-meta, and a Site tab in the admin screen. The compatibility mu-plugin leavessite-*routes with the full site. - Page package improvements. An attachment can be an item on its own (by ID, upload path or URL). Snippet posts have their served files regenerated on import. Packaged meta is unserialized before it is stored; 0.1.0 stored ACF arrays double-serialized.
0.1.x#
The first versions.
- Database export and import. Chunked export to
.sql.gzwith a metadata header, optional prefix rename and exclusions (transients, spam comments, revisions). Streaming import into_bbmig_temp tables, swapped in with oneRENAME TABLE, with a backup first and preserved options restored afterwards. - Find and replace. Serialized-safe, working on the serialized text and rewriting string lengths; JSON-escaped and
URL-encoded forms of each pair; a standalone test in
tests/replace-test.php. - Push and pull between two sites over signed REST requests, with the three per-site switches and automatic replacement pairs from the handshake.
- File sync of whole scopes: uploads, themes, plugins.
- Page packages as a zip, by push or by pull.
- The compatibility mu-plugin, so a half-copied theme or plugin cannot break the transfer delivering it.
- Admin stepper. Tools → BB Migrate, with a resumable job engine shared by the admin screen (one short request per step) and WP-CLI.