TIM Backup releases
Wordpress Backup Plugin mit vielen Funktionen.
by TIM Plugins · github.com/didou7377/tim-backup-free · website
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/didou7377/tim-backup-free/releases/download/v0.4.0/tim-backup-v0.4.0.zipTIM Backup is a security-focused local backup plugin for single-site WordPress.
It creates full or database-only format-v2 backup folders, verifies them, retains
up to three local copies, and provides authenticated component downloads plus
staged, resumable restore. A Free full restore replaces the database and regular
WordPress files contained in the archive without component selection. The
currently running TIM Backup plugin remains protected so recovery and rollback
stay available. A database-only backup restores only the database. Current
wp-config.php, .env*, .git, and .svn content is preserved because these
paths are excluded from full archives.
Full restore requires the standard WordPress directory layout, a writable parent directory on the same filesystem for private staging and rollback, and enough free space. Files are replaced individually through journaled atomic renames; the WordPress root remains available. If any preflight requirement is not met, restore stops safely before activation. Individual archived website files up to 2 GiB are supported. Files that cannot fit in one part are split into authenticated chunks of at most 190 MiB and reassembled with a final hash check. A hidden combined database-and-file rollback preserves the pre-restore state for ten days after success, without consuming a normal backup slot. Another restore remains blocked until that rollback is used or removed.
Format-v2 restore entries and activation/rollback operations are kept in
authenticated, append-only JSONL indexes inside the private restore-<jobid>
workspace. WordPress Options contain only bounded counts, hashes, byte cursors,
and write-ahead intent; they never contain the complete v2 file or operation
lists.
Requirements
- WordPress 6.5 or newer
- PHP 8.1 or newer
- PHP ZIP extension
- Native PHP sodium secretstream and ZIP extensions
- Writable
WP_CONTENT_DIR/tim_backupdirectory (orTIM_BACKUP_STORAGE_DIR) - Standard WordPress content, plugin, and must-use plugin directory layout
- Writable WordPress parent on the same filesystem with enough staging space
- Single-site WordPress
Development
English is the source language. Every user-facing string must use WordPress
internationalization functions with the tim-backup-free text domain. German
translations are bundled under languages/.
Install development dependencies:
composer install
npm ci
Run the project checks:
composer check
npm test
The npm test suite parses every production PHP file, boots the plugin on the current WordPress release in WordPress Playground, creates and verifies backups, exercises safe staged file restore cancellation, rejects unsafe archive state, tests protected three-archive rotation, validates German localization, and runs the official Plugin Check plugin. GitHub Actions additionally performs destructive database-only and full restore tests against MariaDB in an ephemeral WordPress installation, including combined file/database rollback.
The complete product scope, architecture, security requirements, release process,
and current status are maintained in PROJECT.md.
Security
Do not publish suspected vulnerabilities in a public issue. Follow
SECURITY.md to report them privately.
Each logical component is stored as an authenticated secretstream-encrypted
.zip.enc part whose persisted encrypted container has a hard 200 MiB limit.
Production backup creation is a persistent signed job. Database table-engine
preflight is resumable, while the actual InnoDB repeatable-read snapshot is
deliberately exported in one long, streaming request because a transaction
cannot safely cross PHP requests. MySQL/MariaDB creation briefly acquires
FLUSH TABLES WITH READ LOCK, starts the snapshot, captures and binds the exact
InnoDB table set with transaction-lifetime metadata locks, and immediately
releases the global lock. Creation fails before any part is written when the
database account cannot acquire it. Server/proxy hard timeouts can therefore
limit very large databases; the phase is discarded and restarted in full after
interruption, never resumed from an inconsistent transaction.
Filesystem discovery is request-bounded with an authenticated disk queue.
Visiting a directory captures only its direct names (no stat or hashing) into a
private authenticated JSONL snapshot; later requests process those names in
small batches. A directory may contain at most 50,000 direct entries. The v2
format supports up to 250,000 logical files and 2 TiB total site payload,
subject to available local disk and hosting limits.
Files larger than the normal part payload are copied into a private immutable
snapshot in durable steps of at most 16 MiB. Source identity is checked before
and after every step, and interrupted bytes are truncated to the last signed
cursor. Their signed records use sha256-chunks-v1: every chunk has its own
SHA-256 and the logical file identity is a domain-separated root over the
ordered chunk metadata. Restore verifies that root incrementally without
rehashing the complete multi-gigabyte file in one request.
Before encryption, every closed plaintext ZIP is reopened and fully verified
against its signed internal manifest. Creation tracks global entry collisions
in disk-backed 16-bit buckets. The final check then authenticates backup.json,
the exact folder set, encrypted sizes, hashes, and headers without decrypting
parts again or aggregating a site-wide entry map. Backup and restore never build
a whole-site source or combined ZIP. At most one plaintext part exists below a
site-bound mode-0700 private runtime root outside all recognized web roots and
is removed after use. Journals, locks, keys, snapshots and decrypted parts never
reside in final backup storage. Define TIM_BACKUP_PRIVATE_DIR only when the
automatically selected outside-webroot sibling is unavailable.
Plaintext files are mode 0600; startup scavenging removes only strictly named,
stale plugin workspaces. backup.json and every ZIP-local manifest.json are
site-bound and HMAC-signed; encrypted and plaintext hashes are verified before
restore.
The encryption key is intentionally derived from the original WordPress salts
and relevant site URL binding. TIM Backup does not place those salts, the key,
or wp-config.php inside its backups. A complete externally stored backup
therefore consists of its signed backup.json plus every listed .zip.enc
part, and it can be decrypted only with the original WordPress salts and
matching site binding. Keep a separate, access-controlled recovery copy of
wp-config.php or at least the original salts outside tim_backup; never store
that recovery material beside publicly reachable backup files.
Apache 2.2/2.4 and IIS deny files protect the final storage root and directory
listings are disabled. Setup and periodic backup creation additionally perform
a cache-busted random-canary loopback request; only an explicit 403, 404 or 410
is accepted. An unreachable or inconclusive loopback fails closed. Nginx does
not read .htaccess; deployments using Nginx must add:
location ^~ /wp-content/tim_backup/ { deny all; return 404; }
Adapt the URL when WP_CONTENT_DIR or TIM_BACKUP_STORAGE_DIR is customized.
Authenticated backend downloads use only an indexed backup ID and a validated
manifest or component selector. Nginx protection remains required even when all
downloads use the authenticated backend. FTP/SSH access remains available to
server administrators.
WordPress.org
readme.txt is the canonical WordPress.org directory description. Keep its stable
tag, compatibility metadata, changelog, and screenshots synchronized with every
release.
License
GPL-2.0-or-later. See LICENSE.
Releases
4 releases. Each count is every asset in that release; expand a row for the breakdown.