Fix: on the Scan page, the vulnerability and file-integrity scan progress modal could appear hidden behind its own backdrop. The modal is mounted on the page body — outside the plugin’s styling scope — so its brand colour variables weren’t resolving and the card rendered transparent. The modal now carries its own tokens and displays correctly. No change to scanning behaviour.
0.1.5
Authorisation: the integrity scan-control endpoints (start, tick, cancel) and the baseline and finding-resolve endpoints now enforce the Operator gate directly in their REST permission_callback — administrator capability plus an unlocked Operator session — because advancing a baseline rewrites the trusted file fingerprint (a security-state change). Read-only endpoints (CVE scan, scan status, audit verify) continue to require the administrator capability only. Locked requests return a clear, actionable 403.
Removed remaining “free tier / upgrade” wording from the plugin header description to match the rest of the plugin: Defender Lite is free and fully functional, with the separate plugin described for information only.
0.1.4
Guidelines compliance. Audit-log retention is now a free, user-configurable setting (default 90 days, set to 0 to keep everything forever) — it is no longer presented as a paid limit. Nothing in the plugin is gated behind a licence, tier, quota, or time limit; every feature is free and fully functional.
The “More Security” page now describes Ghostables Defender purely as a separate, more advanced plugin available from ghostables.io — no locked tiles, no “unlock”, no in-plugin upsell or licence-key entry.
All JavaScript and CSS is now loaded through wp_enqueue_*. The previous inline and blocks (the REST helper, scan modal, onboarding wizard) moved to enqueued assets/js/admin.js, assets/js/onboard.js, assets/css/onboard.css, and assets/css/login.css. Inline onclick handlers and inline style attributes were replaced with delegated event listeners and CSS classes.
No change to the actual security features: vulnerability scanning, file integrity, hardening, two-factor authentication, Operator gate, and the tamper-evident audit log all work exactly as before.
0.1.3
Plugin Check round-2 cleanup. Fixed the only remaining ERROR (a $wpdb->prepare() call in the CVE scanner that concatenated time() into the SQL — now bound as %d), collapsed two multi-line $wpdb->prepare() calls onto single lines so the phpcs:ignore directive actually lands on the offending line, suppressed the PrefixAllGlobals sniff on view templates (they are require()’d inside controller methods, so their variables are method-local at runtime even though PHPCS sees them as global), and wrapped uninstall.php’s body in an immediately-invoked closure so its working variables are genuinely function-scoped. No functional or behavioural changes.
0.1.2
Plugin Check cleanup: switched all filesystem operations to WP_Filesystem; sanitised every superglobal read with wp_unslash() + sanitize_text_field() / esc_url_raw(); annotated every deliberate direct $wpdb query with the rationale; prefixed all view-file local variables with gdef_ to satisfy the PrefixAllGlobals rule.
No functional changes — all behaviour, option keys, DB schemas, REST routes, and admin UI are unchanged.
0.1.1
Vulnerability feed switched from Wordfence Intelligence to the public WordPress Vulnerability Database (wpvulnerability.net). Same coverage, GPL-compatible licensing, per-component 24h cache.
Two-factor QR code is now rendered locally in the operator’s browser using a bundled MIT-licensed library. The TOTP secret is no longer transmitted to a third party.
Two-factor authentication now blocks XML-RPC and application-password channels for any user with 2FA enabled, closing the previous bypass.
Two-factor recovery codes are stored as password_hash() values rather than plaintext.
Brute-force throttle added to the Operator PIN, the Operator recovery code, and the 2FA challenge — 5 failures in 5 minutes triggers a lockout with exponential backoff up to 1 hour.
Audit chain upgraded from unkeyed SHA-256 to HMAC-SHA-256 with a chain key. The key is read from a GDEF_LITE_AUDIT_KEY wp-config constant when present, otherwise auto-generated and stored as an option. Existing pre-upgrade rows remain verifiable under the legacy scheme.
The audit log no longer trusts X-Forwarded-For or CF-Connecting-IP headers by default — opt in via the GDEF_LITE_TRUST_PROXY wp-config constant or the gdef_lite_trust_proxy filter when the site genuinely sits behind a reverse proxy.
Hardening: nginx server-block snippet for blocking PHP execution in /uploads is now generated on the Hardening page (Apache .htaccess output unchanged).
Admin pages no longer fetch Google Fonts from a CDN — system font stack is used instead.