v1.7.7

External security audit + GPL switch

Full security, functional and code audit. All findings fixed. License switched to GPL v2+ (WordPress.org-repository-compliant). The ~84 layers are now classified into three maturity tiers: 39 Stable, 39 Beta, 6 Labs (default-hidden, opt-in via Security → Advanced).

🛡 Security (critical / high)

  • Path traversal in File-Browser restore fixed — crafted entry names could bypass the realpath check, allowing writes outside ABSPATH.
  • SSRF in Multi-Push receiver closed — pull_url is now validated against private/loopback/link-local IPs (v4+v6) and non-https schemes.
  • Backup directory protection: random filename suffix from 6 → 24 chars (62²⁴ brute-force resistant), plus web.config (IIS) and index.php-404 in addition to .htaccess. Protects Nginx hosts too.
  • Zip-Slip / zip-bomb / symlink protection via new ZipSafe class in every extract path (restore, anonymizer, file-browser).
  • DOM-XSS from backup contents (imported backups could trigger cross-admin XSS) fixed by consistent escaping of all innerHTML sinks.
  • PBKDF2 iterations raised to 600,000 (NIST/OWASP 2024+). Legacy RES1 path keeps 200,000 for backwards compatibility.
  • SHA-256 verification on backup import: optional "Expected SHA-256" field on the upload form, server verifies via hash_equals before touching the file. Wire tampering and corruption are detected. Hash chip in backup list with click-to-copy.
  • Content-Disposition header injection fixed: RFC 5987 with ASCII fallback + UTF-8 encoded variant, plus X-Content-Type-Options: nosniff.

🐛 Functional regressions (critical)

  • 11 killer features that could not be activated (Auto-Heal, Webhook-Trigger, 2FA-Guard, Watchdog, Bandwidth-Throttle, Maint-during-Backup, Magic-Link-TTL, Anonymizer-Rules) — schema whitelist did not contain the keys. Toggle appeared to save, value silently discarded. Fixed.
  • Encryption magic mismatch: write path used RES1, import magic-byte check looked for BKSRSV → self-encrypted backups got rejected on import. Fixed via shared Encryption::is_known_magic() source.
  • Version inconsistency: plugin header showed 1.7.7, readme.txt stable tag 1.0.0. Synced plus new tooling (bin/sync-version.php) and CI gate to prevent future drift.
  • Logs tab hung at "Loading…" (and 12 other AJAX endpoints silently broken): autoloader switch no longer eager-loaded file-bottom add_action() calls. All migrated into boot() methods, plus new test forbidding the anti-pattern.

🏗 Architecture cleanup

  • PSR-4 autoloader replaces 95 require_once lines with lazy class loading.
  • Encryption rewritten as streaming (RES2 format, chunked AES-256-GCM with per-chunk AAD): now scales to 25-GB backups instead of OOM at ~256 MB. Legacy RES1 backups remain decryptable.
  • class-admin.php 2097 → 909 LOC (-57 %): 6 large tabs split into dedicated classes under includes/admin/class-tab-*.php. backsta.php 467 → 209 LOC (-55 %).
  • 113 default settings centralized in SettingsSchema::defaults() — single source of truth. Tests prevent drift between defaults and toggle whitelist.

🧪 Trust / distribution

  • License: GPL v2+ (previously Proprietary). Plugin is now WordPress.org-repository-compatible and GPL-compliance-compliant.
  • PHPUnit test suite with 19 tests / 38 assertions: encryption roundtrip + tamper + wrong-password + legacy-RES1, zip-slip protection, schema consistency, autoloader coverage, version sync, cross-class method resolution.
  • CI on PHP 8.0 / 8.1 / 8.2 / 8.3 with lint + version check + PHPUnit. README, CONTRIBUTING, SECURITY (with audit history), CHANGELOG.
  • Feature registry with Stable/Beta/Labs tier system: 39 stable, 39 beta, 6 labs (default-hidden). Toggle in Security → Advanced.

v1.7.0 – v1.7.6

Major feature release

The 36-layer stack becomes the 60+ layer stack. 27 new features in three themed waves — Recovery & Resilience (layers 38–47), Visibility & Diagnostics (48–55), UX & Polish (56–63). Plus hard fixes for race conditions in the backup pipeline.

Wave 1 — Recovery & Resilience (layers 37–47)

  • ⬆️ Layer 37 · Backup-Import. Upload backup ZIPs directly from the browser — no FTP needed.
  • 🤖 Layer 38 · Auto-Heal. Anomaly detection flags suspected hack → automatically restore last clean backup (cooldown to prevent loops).
  • 📈 Layer 39 · Speicher-Prognose. Linear regression on backup sizes → "in 23 days your storage will be full".
  • 🔍 Layer 40 · Drift-Detection. "Since last backup: +12 posts, +3 plugin files, +1 admin" — early hack warning.
  • 📄 Layer 41 · Disaster-Recovery-Dokument. Printable HTML with all restore info for off-site storage.
  • 🔮 Layer 42 · Pre-Backup-Estimate. Before clicking: "240 MB · 3:24 min · needs 510 MB free".
  • 🔗 Layer 43 · Magic-Restore-Link. Signed token URL per backup. Customer restores without WP login. Single-use, 24h expiry.
  • 🪞 Layer 44 · Dedupe. Finds practically-identical backups (same file count + size cluster). Saves 50–80% storage.
  • 🕵️ Layer 45 · Hack-Forensik-Timeline. Walks last 10 backups, finds when extra admin / PHP in /uploads appeared.
  • 🚧 Layer 46 · Maintenance-Mode während Backup. Prevents inconsistent DB dumps during ongoing orders.
  • Layer 47 · Webhook-Trigger. GitHub Action / CI/CD triggers backup via HMAC-signed REST route.

Wave 2 — Visibility & Diagnostics (layers 48–55)

  • Layer 48 · WP-Cron-Replacement-Helper. Heartbeat tracking + copy-pasteable system-cron snippets.
  • 🧙 Layer 49 · Restore-Symptom-Wizard. Quiz "what is broken?" → recommends the right backup with reasoning.
  • 📦 Layer 50 · Plugin-/Theme-Inventory-Diff. Before restore: what gets removed / reinstalled / downgraded.
  • ⛓️ Layer 51 · Audit-Log Hash-Chain. Tamper-evident event log with SHA-256 hash chain. Compliance: ISO 27001, SOC 2, DORA.
  • 🦮 Layer 52 · Backup-Watchdog. Escalating email cadence on failed streaks + persistent sitewide admin banner.
  • 🛡 Layer 53 · GDPR-Anonymizer. Produces "anon-..." variant with pseudonymized PII. Safe to share.
  • 📤 Layer 54 · Multi-Site-Push. 1 backup → N remote sites in one click. Killer for agencies.
  • Layer 55 · Restore-Conflict-Detection. "Restore would lose 47 orders" BEFORE you click.

Wave 3 — UX & Polish (layers 56–63)

  • 🟢 Layer 56 · Admin-Bar-Status-Pill. "Backsta ✓ OK / ⚠ Warn / ✕ Crit" visible on every WP admin page.
  • 📺 Layer 57 · Live-Backup-Stream. Real-time current task, file cursor, speed (files/s) while backup runs.
  • 🏷 Layer 58 · Smart-Backup-Naming. Instead of cryptic timestamps, automatically before-woocommerce-9.5.zip.
  • 🚦 Layer 59 · Bandwidth-Throttle. Cloud upload limit prevents backup from strangling live traffic.
  • 🕰 Layer 60 · Time-Machine-Slider. Visual drag slider through backup history with live preview.
  • 🔐 Layer 61 · 2FA-Guard. TOTP code required for restore/delete/anonymize/push. Protects compromised sessions.
  • 🌐 Layer 62 · Public Status-Page. Tokenized readonly URL for customer display without WP login.
  • 🪄 Layer 63 · Smart-Exclude. Finds large worthless tables (transients, Wordfence blocks, logs). Often reduces backup size by 50–90%.

Hardening & bug fixes

  • Per-job file lock in tick_one() prevents race between WP-Cron and AJAX status polling — the bug that produced 192 KB DB dumps in 24-table backups.
  • Job lock in start_now(): parallel jobs get merged instead of shredded.
  • DB dump end-of-file marker validation — truncated dumps no longer slip through.
  • Final-ZIP validation: < 1 KB get deleted instead of persisted (prevents 579-byte ghost backups).
  • Hook subscriber crashes can no longer retroactively mark a backup as "failed".
  • Anomaly detection ignores incremental backups (legitimately small, false alarms).

v1.6.0 – v1.6.2

Diagnostics wave

Eight new diagnostics and visibility layers (48–55). Plus reorganized tab navigation and a polished backup-profile form with Google Drive picker.

New layers

  • Layer 48 · WP-Cron-Replacement-Helper. Heartbeat tracking + copy-pasteable system-cron snippets.
  • 🧙 Layer 49 · Restore-Symptom-Wizard. Quiz "what is broken?" → recommends the right backup.
  • 📦 Layer 50 · Plugin-/Theme-Inventory-Diff. Before restore: what gets removed / reinstalled / downgraded.
  • ⛓️ Layer 51 · Audit-Log Hash-Chain. Tamper-evident event log. Compliance: ISO 27001, SOC 2, DORA.
  • 🦮 Layer 52 · Backup-Watchdog. Escalating email + sitewide admin banner on failed streaks.
  • 🛡 Layer 53 · GDPR-Anonymizer. "anon-..." backup with pseudonymized PII. Safe to share.
  • 📤 Layer 54 · Multi-Site-Push. 1 backup → N remote sites in one click.
  • Layer 55 · Restore-Conflict-Detection. "Restore would lose 47 orders" BEFORE you click.

UX & polish

  • Tabs reorganized: action → status → config → system (instead of alphabetical).
  • Backup profile form completely redone — sections, "Active" toggle, target checkbox-cards with availability indicator.
  • Anonymized backups (anon-…) are now visible in the backup list with a safety badge.

v1.5.0 – v1.5.1

Recovery wave

Eleven new recovery and resilience layers (37–47). The 36-layer stack becomes the 47-layer stack.

  • ⬆️ Layer 37 · Backup-Import. Upload backup ZIPs directly from the browser — no FTP needed.
  • 🤖 Layer 38 · Auto-Heal. Anomaly detection flags suspected hack → automatically restore last clean backup.
  • 📈 Layer 39 · Speicher-Prognose. Linear regression → "in 23 days your storage will be full".
  • 🔍 Layer 40 · Drift-Detection. "Since last backup: +12 posts, +1 admin" — early hack warning.
  • 📄 Layer 41 · Disaster-Recovery-Dokument. Printable HTML with all restore info for off-site storage.
  • 🔮 Layer 42 · Pre-Backup-Estimate. Before clicking: "240 MB · 3:24 min · needs 510 MB free".
  • 🔗 Layer 43 · Magic-Restore-Link. Signed token URL — customer restores without WP login.
  • 🪞 Layer 44 · Dedupe. Finds practically-identical backups, saves 50–80% storage.
  • 🕵️ Layer 45 · Hack-Forensik-Timeline. Finds when extra admin / PHP in /uploads appeared.
  • 🚧 Layer 46 · Maintenance-Mode während Backup. Prevents inconsistent DB dumps during ongoing orders.
  • Layer 47 · Webhook-Trigger. GitHub Action / CI/CD triggers backup via HMAC-signed REST.

v1.4.0 – v1.4.4

Quality & cleanup

Quality pass: critical bug fixes in the download and restore paths, plus cleanup of the layer stack. Health Score (layer 19) and Backup Calendar (layer 30) removed — they no longer added value alongside the new status/watchdog cards.

  • Backup download via admin-post.php with capability + per-file nonce instead of direct wp-content URL (was 403, blocked by .htaccess).
  • Imported backups (imported-…zip) now appear in the list — previously blocked by 16 code paths because the "backsta-…" pattern was hardcoded.
  • Staging creation lets you explicitly choose the source backup instead of always "latest".

v1.3.0

Pro tooling

Six new layers (31–36) for demanding setups: pre-backup DB optimization, cold-storage tiering in S3, native chat notifications, auto-recovery on site-down and granular role permissions.

  • 🧹 Layer 31 · Pre-Backup DB Optimization. Cleans revisions, auto-drafts, spam, expired transients before each backup.
  • 🧊 Layer 32 · Cold-Storage-Tiering. Auto-move old S3 backups through STANDARD_IA → GLACIER → DEEP_ARCHIVE. Saves 60–90% cloud cost.
  • 🧩 Layer 33 · Pre/Post-Backup-Hooks. WP action hook, webhook URL, optional shell command (gated via wp-config).
  • 💬 Layer 34 · Chat-Notifications. Native Slack blocks, Discord embeds, Teams message cards.
  • 🚑 Layer 35 · Auto-Recovery on Site-Down. External monitoring reports 5xx → automatic restore with 30-min cooldown.
  • 🛂 Layer 36 · Granular Role Permissions. Custom caps: editor can e.g. only start backups + read logs, restore stays admin-only.

v1.2.0

Operations & trust

Eleven new layers (19–29) for trust, recovery and operations. Shamir Key Recovery, anomaly detection, immutable storage, webhook-triggered restore — plus backup profiles, SQL diff, restore-time estimator and more.

  • 🗝️ Layer 20 · Shamir Key Recovery. Split encryption key into 5 shares — any 3 reconstruct it.
  • 📊 Layer 21 · Anomaly Detection. Early warning on sudden size/file-count explosion (hack signal).
  • 🩺 Layer 22 · Pre-Restore Compatibility-Check. Check backup's PHP/WP/MySQL version against live site.
  • 🔒 Layer 23 · Immutable Storage / WORM-Lock. S3 object-lock — ransomware can't overwrite backups.
  • 🪝 Layer 24 · Webhook-Triggered Restore. External tools can restore pinned backups via REST endpoint.
  • Layer 25 · Restore Time Estimator. "Restore will take ~4 min" based on past restores.
  • 📐 Layer 26 · SQL-Diff zwischen Backups. Which table rows are new/changed/gone between backup A and B?
  • 🎚 Layer 27 · Backup-Profile. Multiple parallel strategies: "Daily DB → S3" + "Weekly Full → S3+GDrive".
  • ⬇️ Layer 28 · Direct-Restore aus Cloud. Restore directly from S3/FTP/Drive without local download.
  • 📝 Layer 29 · Per-Backup Notes & Tags. "before-shop-migration", "after-theme-update" — note and filter per backup.

v1.1.0

Major feature release

Six new layers (13–18), one-click cloud connect, dozens of quality-of-life fixes. The 12-layer stack becomes the 18-layer stack.

New layers

  • 📁 Layer 13 · File-Browser & Single-File Recovery. Tree view through every backup. Preview a single file (source-highlighted), download or restore it surgically — without touching the rest.
  • Layer 14 · Pre-Restore Safety-Snapshot. Before any restore, a 24h safety snapshot is captured automatically. If something breaks: one-click undo back to pre-restore state.
  • 🌐 Layer 15 · Multi-Destination (3-2-1). Parallel replication to up to four destinations (Local + S3 + FTP + Google Drive). Classic 3-2-1 rule automated.
  • 🧬 Layer 16 · Backup Comparison. Compare two arbitrary backups side-by-side. Which files are new? Which tables have grown?
  • 🧠 Layer 17 · Smart Schedule. Automatically learns your site's low-traffic window (based on Insyta data or server load) and shifts backups into it.
  • 🔬 Layer 18 · File Forensics. Index of all files across all backups: NEW / MODIFIED / STABLE / DELETED. Detects hot-spots = potential hacker activity.

Onboarding

  • 🔌 One-click cloud connect for Google Drive. No Google Cloud project, no OAuth credentials, no redirect URI required. The Backsta OAuth hub on backsta.io handles the dance. Classic self-hosted mode remains available for power users.

Fixes

  • 🕐 Time zones: backup timestamps and schedule calculations now respect the WordPress time zone (was UTC).
  • 🔍 Selective Restore: live search and bulk-select for tables/files (was unusable with 1000+ entries).
  • 🗂️ Version Archive: ZIP-upload-overwrite now correctly triggers the archive (previously: "0 versions" despite theme upload).
  • 📧 Notify diagnostics: log of last 20 mail/webhook attempts with status & error text directly in the Notify tab. Plus "no mails arriving?" hint with SMTP plugin recommendations.
  • 🚀 Staging diagnose: 4-point health check per staging env with auto-repair button. Solves the common "staging URL returns 404" issue.
  • 📝 Version Archive: HTML tags in description text now render correctly (were previously shown as plain text).

v1.0.0

First stable version

Initial public release after 6-month closed beta. 12 backup-stack layers fully implemented.

  • 📦 Backup (DB + Files) with incremental and differential modes.
  • 🛡️ Pre-update auto-backup with live progress bar directly on the WP updates screen.
  • 🗂️ Version Archive (plugin/theme rollback by version number).
  • 🔬 Restore Self-Test (weekly dry-run against a sandbox schema).
  • 🔍 Backup Re-Verify (sha256 + ZIP consistency across all backups).
  • 🎯 Selective Restore (cherry-pick individual tables/files).
  • 🔀 Diff Restore (backup A vs. backup B, apply delta only).
  • 🔐 GPG/HMAC signing (detached .asc or .hmac, compliance-ready).
  • 🚀 Push-to-Staging (isolated table prefix, dedicated URL).
  • 🔄 Transfer Resume (S3/FTP resume after connection drop).
  • ✋ Two-Step Restore Confirmation (e-mail confirmation link).
  • ☁️ Cloud-only Mode (stream directly to S3/FTP/GDrive without local disk).
  • 📜 DSGVO-compliant logs, Audit-Trail.
  • 🇩🇪 Multilingual: DE / EN.

v0.9 — Beta

Closed Beta
  • 👥 Closed beta with ~30 hand-picked agencies.
  • 📊 Performance tuning for large sites (5–50 GB).
  • 🐛 ~40 bugfixes based on beta feedback.

Feature requests and bug reports to support@backsta.io.