Trasloco handles full WordPress databases, users, media, and potentially secrets. Do not publish generated archives or logs to the web.
- Administrative pages require
manage_options. - Asynchronous operations use signed, four-hour, operation-scoped tokens. The permanent site secret is never sent to the browser.
- Backups download through an authenticated
admin-post.phphandler with an action-specific WordPress nonce. - A restore can replace the current session, so the signed token can authorize continuation after users are migrated. Treat a leaked token as sensitive until it expires.
New installations create Apache and IIS rules that deny direct HTTP requests for .wpress. Existing Apache rules are upgraded. The temporary working folder blocks HTTP access on Apache and IIS.
Nginx ignores .htaccess and web.config. Add a denial rule in your vhost before using the plugin on production. Example (adapt paths to your setup):
location ~* ^/wp-content/trasloco-backups/ { return 403; }
location ~* ^/wp-content/plugins/trasloco/storage/ { return 403; }Local anonymous HTTP fixtures on 2026-10-14 returned 403 for a .wpress archive, its JSON manifest, an arbitrary-extension temporary file and plugin storage on Apache 2.4.67 using Trasloco's generated .htaccess and on Nginx 1.31.6 using the rules above; a public page returned 200 on both. This validates those local configurations only. Check the effective production vhost and reverse-proxy/WAF behavior from outside the site while logged out.
If WordPress is installed in a subdirectory, update the prefix. If the folder was renamed by a ZIP installation, update the plugin path as well. Prefer keeping backups outside the document root when your hosting permits it. On IIS, existing web.config files from older releases may need manual replacement with the new template.
Verify from a logged-out/incognito browser that all direct archive URLs return 403 or 404, not 200. Random filenames and directory-listing blocks are not a substitute for download authorization.
- Make an independent off-site backup of the destination (files and database).
- Verify available disk space and PHP/MySQL compatibility.
- Test a full restore on a staging clone.
- Run the migration and confirm the old account credentials work.
- Verify pages, images, plugins, forms, permalinks and WooCommerce data where relevant.
- Remove obsolete archives from the server.
The database exporter reads tables and row batches over multiple queries; it does not hold one transactionally consistent point-in-time snapshot across the entire database. A store accepting orders, payment callbacks, webhooks or background Action Scheduler work can therefore change between related reads. The Export page displays a warning when WooCommerce is active; before exporting a live store, enable maintenance mode and pause checkout, incoming integrations and queued order work until the export finishes. A storage-level database snapshot or a separately tested database-native backup is preferable when the store cannot be quiesced. Local WooCommerce 11.2.1 fixtures verify that a normal order, refund, product line, metadata and note survive backup, SQL-failure recovery and restore replay with both HPOS and legacy order storage. This does not test writes concurrent with export, HPOS synchronization/backfill, other WooCommerce versions or order-related extensions; verify those on an isolated staging restore before production use.
- Stopping a failed SQL import cannot automatically reverse MySQL DDL such as DROP TABLE.
- SQL errors now stop the restore, but a previously modified destination must still be recovered from an independent backup.
- Current CLI smoke tests do not prove compatibility on real hosting, Nginx, multisite, or cross-version database imports.
- Keep migrating production sites in a maintenance window, especially stores with ongoing orders.
Please report security problems privately to the repository owner before publishing exploit details.
In wp-config.php, before WordPress loads the plugin, define a location outside your HTTP document root:
define( 'TRASLOCO_BACKUPS_DIR', '/srv/private/wordpress-backups' );Create the directory with permissions that allow the PHP/CLI runtime to write it. This is opt-in: existing archives are not moved automatically. If changing the path, move your existing backups separately and verify permissions. The WordPress Backups screen and WP-CLI use the configured path.
Archives and their temporary files must never be available over HTTP, even for a short time. Updated Apache and IIS rules deny the entire backup directory. For Apache, a legacy folder's rules are appended with a new directory-deny directive; for IIS, update an older web.config manually, since the plugin does not overwrite existing custom configuration. Nginx requires the vhost denial rule above, including temporary filenames.
Run a logged-out HTTP check for /wp-content/trasloco-backups/index.php and for a temporary test file with an arbitrary extension; both must return 403/404. Do not decrypt to a publicly accessible directory unless its HTTP access has been disabled.
The extraction routines reject on-disk symbolic-link path components before writing. Existing symlink-based WordPress deployments may need a documented, physical extraction destination; the importer fails closed rather than follow links. Regression tests cover full and selected archive-file extraction through a symlink pointing outside the destination. This is a filesystem-level check, not a replacement for server isolation: malicious processes with concurrent write permissions could still race between validation and fopen. Use private storage and trusted hosting.
Before replacing a site from a local backup, Trasloco checks its SHA-256 manifest if one is present and refuses a mismatch before creating the recovery snapshot or touching destination files/database. Legacy backups and uploaded files without sidecar manifests remain supported; they undergo structural validation but do not have cryptographic origin authentication. SHA-256 sidecars are not signatures and can be forged by anyone who can modify both files.
Interactive AJAX exports, WP-CLI backups, scheduled jobs and automatic recovery snapshots share an exclusive flock mutex plus a private owner lease in the backups directory. The lease persists across the browser's separate export requests, renews while an export reports progress and expires after inactivity. A competing export is refused before it can write a second archive. The local integration covers lease contention, yielding between requests, same-owner resume, handoff and competing workers; it also rejects symbolic and hard-linked lock files without changing their target permissions. Cross-host fencing is only covered when nodes see the same filesystem and that filesystem correctly honors flock; separate private filesystems, NFS behavior and storage power-loss guarantees still need host-level tests.
The REST preflight and health routes require an authenticated administrator (manage_options). On WordPress 6.9 and later, trasloco/site-readiness exposes the same bounded preflight through the Abilities API, with the same capability check and read-only metadata. Its report omits absolute paths and credentials, and remains advisory; it does not prove that HTTP rules or disaster recovery work on the production host.
When Nginx is detected and the backups directory appears to reside under the site's web document root, administrators now receive a translated warning. This is a best-effort heuristic; proxies, container mounts or unusual document roots can bypass detection. A real logged-out HTTP test remains mandatory.
Full backup export intentionally stops if any symbolic link is present under wp-content. Symlinked plugins, themes or uploads can point outside the WordPress content root, and silently skipping them would produce a misleadingly incomplete backup. The exporter checks for links before applying its exclusion filters; regular archive exports do not dereference those links. Remove links or put physical copies of their content inside wp-content, rerun the backup and verify an independent restore. This protection does not prevent all filesystem races against a malicious process with write access.
Extraction errors deliberately do not echo untrusted archive entry names. Archive filenames can contain NUL bytes, newlines, terminal escapes or private-looking text; exposing them through WP-CLI/HTTP error messages is unsafe. Errors remain actionable by reporting the archive as malformed, while details should only be inspected in an isolated offline tool.