Skip to content

v3.2.0 — Rescue Mode + Atomic Batch + Diagnostics

Latest

Choose a tag to compare

@dd-jfranjic dd-jfranjic released this 28 May 20:35
2255457

BugLens v3.2.0 — Rescue Mode + Atomic Batch + Diagnostics

Released 2026-05-28. PR #1.

Motivation

Real incident on chapas.hr 2026-05-28: a partial deploy of a custom MU plugin (loader file uploaded before module files) caused WordPress to fatal-error on every request. BugLens Bridge API became unavailable because it relies on the same WP boot sequence that was failing. Recovery required manual cPanel File Manager intervention.

v3.2.0 ensures AI agents can recover from such situations programmatically, and adds atomic batch-write to prevent the partial-deploy scenario in the first place.

⭐ New Features

🆘 Rescue Mode — standalone PHP endpoint that survives WP fatal errors

  • New file rescue-template.php (ships with plugin) — copied to wp-content/buglens-rescue-{random32}.php on activation
  • Zero WordPress dependency — no wp-load.php, no database, no plugin loading
  • Provides 7 fs operations: read, write, delete, list, info, mkdir, rename
  • New class BugLens_Bridge_Rescue_Security manages install, secret hashing (SHA256), random URL slug generation
  • Default DISABLED — returns HTTP 503 until secret configured via:
    • BugLens_Bridge_Rescue_Security::set_rescue_secret() (programmatic), or
    • BUGLENS_RESCUE_KEY constant in wp-config.php (override)
  • Auto-lockout — 5 failed auth attempts per minute → 1 hour IP ban (file-based counter)
  • Audit log — JSON Lines at wp-content/buglens-rescue-state/audit.jsonl
  • State directory auto-creates with .htaccess Deny (Apache 2.4 + 2.2 fallback)

🔁 Atomic Batch + Verify endpoints

  • POST /fs/batch-write — all-or-nothing N-file write. Max 50 files, 10 MB total, 2 MB per file
    • Pipeline: validate → stage to wp-content/uploads/_buglens-batch-staging/{nonce}/ → verify sha256 → atomic rename → cleanup
    • Mid-rename failure returns partial_commit with list of already-committed files (recoverable state info for client)
  • POST /fs/verify — bulk sha256 verification. Returns per-file {path, exists, size, sha256, matches_expected?}

🩺 Health + Preflight diagnostics

  • GET /fs/health (public, no auth) — WP boot status snapshot: versions (WP/PHP/MySQL), memory used/peak/limit, plugin counts, last 5 error_log lines, rescue mode status, request time. Cache headers ensure always-fresh (LSCWP nocache action + Cache-Control: no-store)
  • POST /fs/preflight — dry-run path validation (parent_exists, writable, blocked) without filesystem changes

🤖 MCP server v3.2.0

5 new tools:

  • batch_write — atomic multi-file deploy
  • verify_files — bulk sha256 assertions
  • health_check — WP boot diagnostics
  • preflight_paths — dry-run validation
  • rescue_call — bypass WP REST entirely via rescue.php (uses BUGLENS_RESCUE_URL + BUGLENS_RESCUE_KEY env vars)

rescue_call sends secret in X-BugLens-Rescue-Key header only (not body) to minimize logging exposure.

🔐 Security fix (CVE-class)

Discovered during v3.2.0 testing on chapas.hr: when DB option buglens_bridge_settings has blocked_paths = '' (empty string), the ?? operator does NOT fall back to default (?? only fires on null). Result: blocked patterns list becomes empty → wp-config.php, .htaccess, .htpasswd ALL readable via /fs/read with any valid API key.

Affected versions: v3.0.0 through v3.1.0.

Fix: defensive empty-string check forces baseline blocked patterns when DB has empty value. Admin can still explicitly customize.

If you're upgrading from v3.0.0–v3.1.0 and used Bridge in production, please verify your buglens_bridge_settings option and rotate any credentials that may have been exposed.

🔄 Changed

  • uninstall.php — explicitly preserves rescue artifacts (buglens-rescue-{slug}.php, buglens-rescue-state/) on plugin delete. Reason: user installed rescue specifically for emergency recovery; removing plugin should not lose that capability. Manual delete via cPanel/FTP if full cleanup desired.

📦 Files

  • 4 new PHP class files in includes/
  • 1 new template at root (rescue-template.php)
  • 1 new MCP tools module (mcp-server/src/tools-v320.js)
  • New docs: docs/rescue-mode.md
  • Updated: buglens.php, mcp-server/src/index.js, mcp-server/src/client.js, mcp-server/package.json, CHANGELOG.md, uninstall.php
  • 1 fix to includes/class-buglens-bridge-security.php

✅ Tested

Live tested on chapas.hr (Plus Hosting Grupa cPanel + CloudLinux + LiteSpeed, WordPress 7.0, PHP 8.3.31):

  • ✓ Rescue endpoint install via set_rescue_secret()
  • ✓ Auth: 403 without key, 200 with valid key
  • ✓ Auto-lockout: 5×wrong key → 5×403, 6th onwards → 429
  • ✓ Atomic batch-write 3 files with sha256 verification
  • /fs/verify returns per-file existence + matches_expected
  • /fs/health returns WP boot status, no longer cached by LSCWP
  • /fs/preflight validates paths without writing
  • ✓ Security hardening confirmed (wp-config.php blocked when defaults active)

Upgrade notes

  1. Download buglens-3.2.0.zip (attached below) → upload via WP Admin → Plugins → Add New → Upload Plugin → Replace.
  2. Plugin activation hook will install rescue endpoint at wp-content/buglens-rescue-{random}.php. Default state: returns 503 (no secret configured).
  3. To enable Rescue Mode, run (via wp-cli or wp eval):
    echo BugLens_Bridge_Rescue_Security::set_rescue_secret();
    Save the returned plain secret to your password manager (shown once).
  4. Update MCP server: npm install -g buglens-mcp@3.2.0 (when published to npm).

Rollback

If anything fails:

  • Restore from v3.1.0 ZIP (re-upload + replace)
  • Delete rescue artifacts (optional): rm wp-content/buglens-rescue-*.php && rm -rf wp-content/buglens-rescue-state/

🤖 v3.2.0 designed and implemented with Claude Code (Opus 4.7).