=== SecureLite Security – Firewall, Malware Scanner & Attack Simulation ===
Contributors: naveenfriendly
Tags: security, firewall, malware scanner, brute force, two-factor
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 0.2.23
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Free firewall, malware scanner, limit login attempts, 2FA and hide login, plus an attack simulation that proves each protection works.

== Description ==

SecureLite Security is a free WordPress security plugin: a firewall, a malware scanner, brute force protection that limits login attempts, two-factor authentication (2FA) and hide login. It also does one thing other security plugins don't: it proves each of those protections works on your own site, with one click.

https://www.youtube.com/watch?v=wMXKVXDOcWo

Most security plugins give you a list of switches and leave you hoping they work. SecureLite adds a button that finds out.

**Run Attack Simulation** runs fifteen real attacks against SecureLite's real protections — SQL injection, XSS, directory traversal, user enumeration, brute force, malicious and executable uploads, XML-RPC abuse, comment spam from bots, password bots without a real browser, attack-tool signatures, a malware sample, PHP execution in your uploads folder, and whether your .git directory or readme.html can be downloaded by anyone — and confirms that a real request to your site actually reaches those protections. It then reports, per protection, whether it would block, is switched off, or failed. Where a setting would fix it, an Enable & re-test button is right there. The result is a printable report you can hand to a client.

It is built to run on a live site. The attacks run inside WordPress, not over the network, so there is nothing for your host's firewall, your CDN or another security plugin to see or react to, no failed logins, and nothing left behind — not even in your security log. You do not need a staging copy.

Everything runs on your site. There is no reverse proxy in front of your domain, so your caching, your CDN and your visitors' real IP addresses all keep working exactly as they did.

= Why you can trust it =

SecureLite is new, so it has no years of reputation to point to. Here is what you can check for yourself instead:

* **Proof, not promises.** Attack Simulation shows you what each protection actually blocks on your own site, and says so plainly when one doesn't. Nothing is hidden to sell you a fix, and it never tells you your site is "secure", only which checks passed.
* **Built not to lock you out.** Two-factor can't switch on until a code from your app has worked, and comes with recovery codes. A new login URL is tested before it is kept. Knowing your username isn't enough to lock you out of your own account. Three ways back in are written down before you ever need them.
* **Nothing about your site leaves your server.** No account, no licence key, no telemetry. The one outbound request, to WordPress.org for official file checksums, is listed under External Services.
* **Every feature is free, for good.** No upgrade nags in your dashboard, and nothing in the plugin will ever move behind a paywall.
* **Clean to remove.** Deactivate it and the lines it added to wp-config.php are given back; delete it and every table and setting goes with it.
* **People you can reach.** Built by PixelGravitas. Support questions are answered in the forum by the people who write the code, and every changelog entry says exactly what changed and why.

= Protection =

* **Firewall** — inspects query strings, POST bodies, cookies, URLs and user agents for SQL injection, XSS, directory traversal and known scanner tools. Blocks attacks from the moment it is installed; a watch-only switch is there if you ever need to check a request. Editors and authors can save a post that explains `javascript:` links or quotes an `onclick=` attribute without the firewall refusing it.
* **Malicious upload blocking** — a virtual patch for the executable-upload vulnerability class, including PHP disguised with an image extension.
* **Brute force protection (limit login attempts)** — persistent per-IP and per-username lockout, surviving cache flushes. Addresses that keep coming back are locked for longer each time, up to 24 hours. Guesses at "admin" count double. Login errors never disclose whether a username exists. A locked username still opens for the right password, so nobody can lock you out of your own account by knowing your login name.
* **Two-factor authentication (2FA)** — scan a QR code with any authenticator app (TOTP, RFC 6238). The QR code is drawn on your own server, so your key never leaves it. You cannot switch it on until you have entered a code your app actually produced, each code signs you in only once, and ten single-use recovery codes are issued at the same time.
* **Hide login (change the login URL)** — move wp-login.php to a secret address and return 404 at the old one. The new address is tested before it is kept, and emailed to you.
* **Malware scanner** — every WordPress core file is compared with the official release, so a web shell dropped into wp-includes or the site root, or a changed core file, is reported as Critical with certainty. PHP, JavaScript and HTML elsewhere get signature and heuristic scanning for backdoors, web shells and packed payloads, and matches in wordpress.org plugins are checked against the official release so unmodified library code is not reported as malware. The database is scanned for injected fake-captcha and redirect scripts that a file scanner would never find.
* **File-integrity monitoring** — event-driven, with a lightweight sweep over the paths attackers actually touch: wp-config.php, .htaccess, mu-plugins, dropins, theme functions.php, and any PHP appearing in uploads.
* **Rate limiting** — refuses floods from one address before the page renders, counted over a rolling minute, with a tighter budget for unauthenticated admin-ajax. Logged-in users are never limited, and genuine Google and Bing crawlers are verified and let through.
* **Smart protection** — when SecureLite is not sure a visitor is a person, it checks their browser instead of refusing them. A real browser passes in a moment, usually without the person noticing; bots that do not run a real browser are stopped before WordPress does any work. Password bots sending logins straight to wp-login.php never reach the password check, a comment sent without your page is checked before it is saved, and a person on a busy shared address who goes over the traffic limit passes the check and carries on instead of being refused. No puzzles, no CAPTCHA, no outside service.
* **Comment spam protection** — refuses comments from bots without any outside service. A bot that posts without loading your comment form, or fills in a box people never see, is turned away, and one person can post only a few comments an hour. People sharing an address (an office, a college, a mobile network) are not refused for each other's comments. People see no change to the form. Trackbacks and pingbacks are switched off.
* **XML-RPC protection** — refuses the two things bots use XML-RPC for: guessing account passwords and pingbacks. Jetpack, apps and tools that connect with an application password keep working.
* **Uploads PHP check** — the exact rule, for Apache/LiteSpeed (.htaccess) or nginx, that stops PHP executing in your uploads folder, and an Attack Simulation check that confirms your server enforces it. SecureLite never edits .htaccess or any other server configuration file itself.
* **Security score** — a local security scanner for your settings, with prioritized findings and one-click fixes.
* **Notifications** — a daily summary and two immediate alerts, sent by your own site. Never one email per blocked request.
* **Post-hack recovery** — log everyone out, regenerate salts, reset passwords, rename the user 1 account.
* **Trusted IPs** — exempt your own address or office range from the lockout and rate limiter, so you can't shut yourself out.
* **Works behind Cloudflare and proxies** — a Cloudflare preset and a trusted-proxy list, so lockouts see each visitor's real address. Forwarded IP headers are only believed when the connection really comes from a trusted proxy, so they cannot be forged to dodge a lockout.
* **Clean removal** — the only file SecureLite writes is wp-config.php, and only when you switch a setting that lives there (the file editor, your trusted-IP line, regenerating keys and salts). Deactivating gives those lines back and reactivating restores them; uninstalling removes them, its tables and its settings entirely. Nothing of this plugin outlives it.

= What's coming next =

SecureLite is new, and these are planned — no dates promised, and nothing already in the plugin will ever move behind a paywall:

* An emailed unlock link on the lockout screen, so getting back in never needs FTP.
* Optional alerts when an installed plugin has a known vulnerability, clearly disclosed and off unless you turn it on.
* A dashboard for agencies looking after many sites.

Tell us what you'd like next in the support forum.

= What this plugin is not =

A PHP plugin cannot stop a volumetric DDoS, and SecureLite does not claim to. For that you want Cloudflare or server-level rate limiting in front of the site. SecureLite owns the depth on the site itself.

= Need help? =

**Free support** is on the WordPress.org support forum, answered by the people who build SecureLite. Every feature is free, so you never need to buy anything to get help.

**Need hands-on help?** SecureLite is made by PixelGravitas, a website maintenance and security team.

* Site already hacked? We remove the malware and close the way in, for a fixed fee agreed before work starts: [WordPress malware removal](https://pixelgravitas.com/website-maintenance/malware-removal/)
* A check needs server-level changes, or you would rather someone looked after the site: [WordPress maintenance and support](https://pixelgravitas.com/website-maintenance/wordpress/)

== Installation ==

1. Upload the `securelite-security` folder to `/wp-content/plugins/`, or install the zip through Plugins > Add New > Upload.
2. Activate through the Plugins screen.
3. Go to **SecureLite > Verification** and click **Run Attack Simulation**. Whatever is not yet protecting you gets an Enable button right there.
4. Optionally visit **SecureLite > Settings** to tune thresholds, hide your login URL, or add your own IP as trusted.

The firewall, rate limiting, login protection, XML-RPC protection and the comment shield are on and blocking from the moment you activate SecureLite. There is nothing to set up first.

== Frequently Asked Questions ==

= How is SecureLite different from other WordPress security plugins? =

The core protection is what you would expect from a good free security plugin: a firewall, a malware scanner, brute force protection, two-factor authentication and hide login.

What is different is how you know it works. Attack Simulation runs fifteen real attacks against your own site, confirms that real requests reach the protections it tested, and shows, check by check, what was blocked, what is switched off and what failed, with one-click fixes. It runs inside WordPress, so it is safe on a live site and leaves nothing behind.

It is also deliberately quiet and private: no account or licence key, no upgrade nags, nothing about your site sent anywhere, and safeguards so you can't lock yourself out.

What it does not do: there is no live threat-intelligence feed (its signatures are updated with each release), and a PHP plugin cannot stop a large DDoS attack. For that, put Cloudflare or your host's firewall in front of the site. SecureLite works alongside both.

= I'm locked out of my own site. How do I get back in? =

Any one of these works without logging in:

1. **Wait.** Login pauses for 15 minutes by default, then opens again. An address that keeps getting locked waits longer, up to 24 hours. The lockout message shows how long is left.
2. **Trust your address.** Add this line to wp-config.php, above the line that says "That's all, stop editing!", using your own IP address: `define( 'SECURELITE_ALLOW_IP', '203.0.113.45' );` If the site runs on your own computer (localhost, XAMPP, Local), your browser reaches it as `::1` or `127.0.0.1`, not your internet address, so list those too, separated by commas: `define( 'SECURELITE_ALLOW_IP', '203.0.113.45, ::1, 127.0.0.1' );`
3. **Switch SecureLite off.** Rename the `wp-content/plugins/securelite-security` folder to `securelite-security-off` using FTP or your host's file manager. The normal login page returns immediately.
4. **With SSH access**, run `wp plugin deactivate securelite-security`.

To be ready before it happens, use **Add my IP to wp-config.php** under Settings > Login protection. Your own address is then never locked out.

Forgot your hidden login address? It was emailed to the site administrator when you set it. Otherwise, option 3 restores the normal login page.

Lost the phone with your authenticator app? See the next question.

= How do I set up two-factor, and what if I lose my phone? =

Go to **Users > Profile** and scroll to **SecureLite Two-Factor**. Scan the QR code with an authenticator app (Google Authenticator, Microsoft Authenticator, Authy, 2FAS) by pointing your phone at the screen, type the 6-digit code it shows, tick the box and click **Update Profile**. If you cannot scan, open "Can't scan?" and type the key into the app instead. The QR code is drawn by the plugin on your own server; your key is never sent anywhere.

SecureLite does not send codes by SMS or email. Your app makes a new code every 30 seconds, even offline, and each code signs you in once.

When two-factor turns on you get ten recovery codes, shown only once. Copy, download or print them and keep them somewhere other than your phone. If you lose your phone, type any one of them in the **Authentication code** box on the login page. Each works once, and you can make a new set from your profile at any time.

Lost your phone and your recovery codes? Any of these gets you back in:

1. **Another administrator** opens Users, edits your account and ticks "Turn off two-factor authentication for this account".
2. **Switch SecureLite off** by renaming the `wp-content/plugins/securelite-security` folder over FTP or your host's file manager. Sign in with your password, rename it back, and set up two-factor again.
3. **With SSH access**, run `wp user meta delete <your-username> securelite_totp_enabled`.

= Is Attack Simulation safe to run on a live site? =

Yes — that is what it is built for. Since 0.2.17 no attack and no login is sent over the network. Each attack is handed to SecureLite's own firewall, lockout and upload rules inside WordPress, as data held in memory, and the result is what those rules would do with it. Your host's firewall, your CDN and other security plugins never see a test, so there is nothing for them to ban your server's address for, and nobody is emailed an alert.

The brute-force test runs SecureLite's real lockout from a reserved test address (192.0.2.x) that no real visitor can have, never yours, and removes its own counters before it finishes — even if you close the tab. Test events never reach your security log or the daily summary. The only requests the simulation makes are ordinary ones: one normal page request to confirm real traffic reaches SecureLite's protections, and file requests that check your server's configuration — whether PHP can run in uploads, and, only if the file exists on disk, whether .git or a version-revealing readme.html can be downloaded.

Every report says what it covers: SecureLite's own protections and the path real requests take to reach them. If a CDN or proxy such as Cloudflare sits in front of your site, the report names it, but its own firewall is not part of the test.

= Will this lock me out of my own site? =

Two-factor cannot be switched on until you have proved it works, and it issues ten single-use recovery codes when you do. Changing your login URL is tested before the change is kept, and switches itself back off if the new address does not answer.

Lockouts are the remaining case, the same as with any plugin that limits login attempts — and there are three ways back in. Lockouts expire on their own after the window you set (15 minutes by default). Adding your IP under Settings > Trusted IPs exempts you in advance. And if you are already locked out and cannot reach the settings screen, add this to wp-config.php:

`define( 'SECURELITE_ALLOW_IP', '203.0.113.45' );`

You can also rename the `wp-content/plugins/securelite-security` folder over FTP, or run `wp plugin deactivate securelite-security`. Better still, set it up before you need it: under Settings > Login protection, **Add my IP to wp-config.php** writes that line for you, checking the result and putting the original back if anything goes wrong. If the file is locked by your host, it tells you why and gives you the exact line to paste. All three ways back in are also on the Support screen and emailed to you once, the first time you save with login protection on.

= My site is behind Cloudflare. Do I need to change anything? =

Yes — turn on **Behind a proxy/CDN** and the **Cloudflare** preset under Settings > General. Without them every visitor arrives from a Cloudflare address, so a lockout aimed at one attacker would lock out everyone sharing that edge. The settings screen tells you when it sees Cloudflare traffic with proxy mode off, and shows which address SecureLite believes you are connecting from.

That address is then trusted immediately, with every protection still active for everyone else. File access alone is enough — you never need database access to recover.

One case is deliberately not a lockout at all. If someone attacks your account from many addresses, your username gets locked — but entering the correct password still lets you in and clears it. Knowing your login name is not enough to keep you out of your own site.

= What happens if I deactivate or delete it? =

Everything goes back. Outside its own database SecureLite only adds lines to wp-config.php — DISALLOW_FILE_EDIT and, if you asked for it, your trusted-IP line — and deactivating hands them back, while activating again restores them. Your settings, trusted IPs and security log survive deactivation untouched, because deactivating a plugin is how people troubleshoot.

Deleting the plugin removes all of it: the wp-config.php lines above, both database tables, every setting, the two-factor secrets and recovery codes, and the scheduled jobs. It only ever removes its own work — a DISALLOW_FILE_EDIT line that was already in your wp-config.php is put back the way you had it, and one that another plugin manages is never touched.

= Does it slow my site down? =

The firewall inspects the request before WordPress renders anything and adds well under a millisecond in normal use. Scanning is scheduled, budgeted and never runs during a page load. Logged-in administrators are never filtered or rate limited.

= Will the firewall block legitimate traffic? =

It blocks from the moment it is installed, with safety nets for the people who run the site: administrators are never filtered, editors and authors saving content are not checked against attack patterns, and logged-in users are never rate limited. If something legitimate is ever caught, the dashboard shows exactly which rule matched and on which parameter, and the watch-only switch lets that traffic through while you look into it.

= Does it stop spam comments? =

It turns away spam from bots without sending your comments anywhere: a bot that posts without loading your comment form, or fills in a box people never see, is refused, and one person can post only a few comments an hour (and one address 20, whoever posts them). It does not judge what a person writes by hand; for that, keep comment moderation on or use a service that reviews comment content. Comments from logged-in users are never checked. When SecureLite is not sure a comment came from a person, Smart protection checks the browser instead of refusing it.

= Will my visitors see a CAPTCHA or a puzzle? =

No. Smart protection checks the browser, not the person: on the login page and pages with a comment form the check runs in the background as the page loads. Someone who sends a form before it finishes, or whose page was saved by a cache, sees a "checking your browser" page for a moment, and then their login or comment goes through by itself. With JavaScript switched off, a comment can still be sent for your approval; logging in needs JavaScript while Smart protection is on. A bot that drives a full browser can pass the check, but then the other protections still apply to it: the hidden field, the per-person limits and the lockout.

= Does it phone home? =

No. Nothing about your site, your users or your security events ever leaves your server. There is no account, no API key, no telemetry and no third-party service.

The one outbound request is to WordPress.org itself, the same servers WordPress uses for its own updates: the malware scan downloads the official checksums for your WordPress version and for any wordpress.org plugin it needs to verify, so it can tell an added or altered file from a genuine one. The request names only the WordPress version and locale, or the plugin's folder name and version — not your site address — and the answer is cached for a week. If WordPress.org cannot be reached, the scan still runs and says that core could not be compared.

Two commitments come with that, and they are permanent. Nothing in this plugin will ever require an account or a key to keep working. And no protection will ever behave differently because you have not connected the plugin to anything — the firewall, the scanner, the lockout and two-factor do exactly the same job either way, forever.

Every protection runs on your own server, which also means no outage anywhere else can affect your site, and nobody but you can see your security events.

= Does it set cookies? =

Only for visitors who pass Smart protection's browser check: a signed pass (`securelite_pass`, plus `securelite_passed` so the check is not repeated) that lasts a day, and briefly the check's answer (`securelite_proof`). They contain no personal information and are not used for anything else. Switching Smart protection off stops them.

= Does it write files on my server? =

Only wp-config.php, and only when you change a setting that lives there. It is edited in place — never copied — checked to be valid PHP before saving, read back afterwards, and restored from memory if the write did not land exactly. SecureLite never writes .htaccess or other server configuration, and keeps no files in your uploads folder: for blocking PHP in uploads it shows you the rule to add and checks that your server enforces it.

= What does it store on my site? =

Security events are written to a table in your own database: login attempts, account and role changes, plugin and theme lifecycle, and firewall matches, each with the client IP and user agent. The table is a rolling buffer capped at the most recent entries, so it cannot grow without bound. Uninstalling the plugin drops it completely.

= Is it compatible with WooCommerce, Elementor and page builders? =

Yes. Logged-in administrators bypass request filtering, so builder and checkout traffic is unaffected. If you do hit a false positive, the firewall log shows the rule involved, and the watch-only switch lets the traffic through while you look into it.

== External Services ==

SecureLite does not send telemetry and does not require an account or an API key. All processing happens on your own server and all security data stays in your own database.

**WordPress.org checksums.** During a malware scan, SecureLite requests the official file checksums for your WordPress release from `https://api.wordpress.org/core/checksums/1.0/` (sending the WordPress version and locale), and for wordpress.org plugins that matched a scanner pattern from `https://downloads.wordpress.org/plugin-checksums/` (sending the plugin's folder name and version). When core files do not match the installed release, it also asks `https://api.wordpress.org/core/version-check/1.7/` for the newest WordPress version (nothing is sent) so it can recognise files from a half-finished update. No site address, user data or file content is sent. Responses are cached for seven days, the newest-version answer for twelve hours. These are WordPress.org services: [Terms of Service](https://wordpress.org/about/terms-of-service/), [Privacy Policy](https://wordpress.org/about/privacy/).

== Screenshots ==

1. Attack Simulation — fifteen real attacks run against SecureLite's protections, plus a check that real requests reach them, with an honest pass, not-enabled or failed result for each, and a printable report.
2. Dashboard — security score, recent firewall blocks, and current malware scanner findings.
3. Firewall — blocked requests with the rule that matched and the parameter it matched on.
4. Login protection — limit login attempts, two-factor (2FA), hide login URL and trusted IPs.
5. Recovery — log out all sessions, regenerate salts, reset passwords, rename the user 1 account.

== Changelog ==

= 0.2.23 =
* Changed: the "malware removal service" and "server hardening" links shown with malware findings and failed checks now open the PixelGravitas request form directly (three fields), with "Security concern or a hack" already chosen (you can pick another), instead of the top of a long page. The link carries only which SecureLite screen it came from — nothing about your site.
* Changed: Attack Simulation's "PHP execution blocked in uploads" check no longer shows "Skipped" on hosts such as Hostinger when there is no PHP file in the uploads folder to test with. If the rule that stops PHP there is in place and the web server is LiteSpeed or Apache (which follow it), the check passes and says it was checked from the server's setup; on nginx, which ignores that kind of rule, it says the folder is not protected. It still never creates a file.
* Improved: visitors on IPv6 are counted by their network block (the first half of the address, a /64) for rate limiting, the hourly comment limits and login lockouts. An IPv6 connection comes with a whole block of addresses, and devices change the rest of the address by themselves, so a bot could get around a per-address limit by using a fresh address for every request. The security log still shows each full address.
* Improved: when you add your own address to Trusted IPs, or to wp-config.php from the "3 ways back in" box, SecureLite offers your IPv6 block instead of the exact address, so it keeps matching after your device changes its address.
* Fixed: the "inactive plugins" and "inactive themes" notices now go away as soon as you delete, activate or switch the plugin or theme, instead of staying until the next background scan. Plugins or themes removed outside WordPress (by FTP or your host's file manager) are noticed the next time you open SecureLite.
* Changed: the Settings page shows the essentials first — Smart protection, how to get back in if you are ever locked out, two-factor and notifications — and everything else is under "Show all settings". A line at the top says whether your settings match what is recommended and names anything that gives less protection, with a link to it; when something under "Show all settings" is set that way, the section opens by itself. No setting was removed, renamed or moved to another page.

= 0.2.22 =
* Changed: SecureLite now blocks from the moment it is installed. The firewall and rate limiting used to start in watch-only mode, so attacks and floods still got through until someone changed a setting. Both now start in Block, and sites already using SecureLite are switched to Block by this update; protections you had switched off stay off. Administrators are never filtered, editors and authors saving content are not checked against attack patterns, logged-in users are never rate limited, and genuine Google and Bing crawlers are verified and let through. Watch-only stays available in Settings for checking a request.
* New: comment spam protection, on by default. Bots that post without loading your comment form, or that fill in a hidden box people never see, are refused, and one person (same name and email from one address) can post 5 comments an hour by default, and one address 20, so people sharing an office, college or mobile network address are not refused for each other. Logged-in users are not checked. Nothing is sent to any outside service. It works with page caching: SecureLite clears the page cache of common caching plugins (LiteSpeed, WP Rocket, W3 Total Cache, WP Super Cache, SiteGround, Breeze, Cache Enabler) once when it starts, and for the first week up to 10 comments an hour sent from copies of your pages cached before the update are held for your approval rather than refused, without an email for each one; the rest are refused. Trackbacks and pingbacks are switched off. Refused and held comments are counted in the daily summary, so a spam flood no longer sends you an email per comment and uses up your host's email allowance.
* Improved: rate limiting counts over a rolling minute. It used to restart its count at the top of every minute, so a flood that straddled the minute could get through; in testing, 300 requests in 10 seconds across the minute were all let through before this change and cut off after it.
* New: Cloudflare is recognised automatically. Visitors are seen by their real address, not as one of a few Cloudflare addresses, so one visitor's limits and lockouts no longer apply to everyone else on Cloudflare. A connection that does not really come from Cloudflare cannot use this to fake its address.
* New: if your host puts a proxy in front of your site and SecureLite has not been told, rate limiting and the hourly comment limit pause instead of treating every visitor as one, and the security score tells you to turn on "Behind a proxy/CDN".
* New: Smart protection, on by default. When SecureLite is not sure a visitor is a person, it checks their browser instead of refusing them, with no puzzle and no outside service. Logins and comments sent without a browser are stopped before WordPress checks a password or saves anything; a person who goes over the traffic limit (for example on a busy office or mobile network) passes the check and gets more room instead of a refusal; an unproven visitor that looks like a script (no browser headers, or blocked by the firewall in the last hour) gets less room. In the first week, comments from pages cached before the update that pass the check go straight through instead of waiting for approval.
* Attack Simulation checks comment spam and password bots without a browser too (fifteen attacks and the reach check).
* Fixed: the daily summary could stop for good without any sign. Its daily task is only created when the plugin is activated, so if it ever went missing, nothing put it back. SecureLite now checks on each visit to the admin area, sets up any missing scheduled task again, and tells you it did.
* Settings > Notifications has a new Status line. It shows when the daily summary last ran and what it did (sent one, or there was nothing to report), when it runs next, and, if the last email failed, the error your site's mailer gave. The Support screen's system report shows the same.
* A failed alert or summary is no longer silent: the mailer's error is kept and shown until the next email goes through.
* Changed: "Block XML-RPC" is now "Protect XML-RPC". It used to refuse every request to xmlrpc.php, which broke Jetpack (and WooCommerce features that use Jetpack's connection) and other services. It now refuses only what attackers use there: logins with an account password, and pingbacks. Application passwords and services' own keys, such as Jetpack's, keep working, so there is no list of exceptions to maintain. A tool that signed in to XML-RPC with your normal password needs an application password instead (Users > Profile > Application Passwords). The setting stays on, and sites update automatically.

= 0.2.21 =
* The "PHP execution blocked in uploads" check now gives a clear answer on many more sites. If your uploads folder already holds a harmless PHP file (many plugins leave an empty "index.php" there), the check asks your server for that real file: refused means PHP is blocked, run means it is not. SecureLite reads the file first and only uses one that contains no code, and it never creates, changes or removes anything in your uploads folder.
* Fixed: on sites whose WordPress address starts with http:// while the host forces https://, this check stopped at the redirect and reported "Inconclusive: the server answered with HTTP 301". It now follows a redirect that only changes http/https or "www.", and nothing else.
* When the check still cannot decide (for example on LiteSpeed hosts with no harmless PHP file in uploads), it explains why and how to check by hand, instead of showing a bare status code.
* The plugin description now says what the simulation does today: it proves each protection works on your own site. The old wording, "attacks your own site", dated from before 0.2.17, when the checks were still sent over the network.

= 0.2.20 =
* Other plugins' notices, promotions and review requests no longer appear inside SecureLite's screens. They used to land in the Agent status card on the dashboard and stretch the page. SecureLite now leaves them out on its own screens only; WordPress update and recovery notices, and SecureLite's own messages, still show. Every other admin screen is unchanged, so those plugins' notices still appear wherever else they normally do.
* Any notice that does reach a SecureLite screen now sits above the cards instead of inside them.

= 0.2.19 =
* Attack Simulation now proves that real requests reach the protections it tests. A new first check sends one normal page request to your site (no attack, no login) and passes only if SecureLite's firewall itself inspected it. If a page cache, your host or another plugin answers instead, the report says so rather than counting it as a pass. Together with the thirteen attack checks, "Every attack was blocked" now means the attacks would be refused on your site, not only by SecureLite's rules in isolation.
* If a CDN or proxy sits in front of your site (Cloudflare, Sucuri, CloudFront, Fastly, QUIC.cloud, LiteSpeed, Varnish), the report names it from the evidence it already has. It is detected, not tested.
* Every report, live and printed, now ends with a plain line saying what was tested and that your host's or CDN's own firewall is not part of the test.
* Fixed: a re-test of the firewall or login checks was meant to make no request to your server since 0.2.17, but still asked for your home page first. It now only does so when a check needs the server's answer.
* The Support screen's local-site lockout hint reads more clearly.

= 0.2.18 =
* The plugin's name now matches its WordPress.org listing: SecureLite Security – Firewall, Malware Scanner & Attack Simulation. Nothing else about the plugin changes.
* The plugin description on the Plugins screen no longer says it makes no outbound connections. The malware scan does ask WordPress.org for official file checksums, as the readme has always disclosed under External Services; the description now says what is true: nothing about your site is sent anywhere.
* A one-minute video on the plugin page shows install to first Attack Simulation.

= 0.2.17 =
* Attack Simulation is now safe to run on a live site with nothing to set up. No attack and no login is sent over the network any more: each attack runs against SecureLite's real firewall, upload, enumeration, XML-RPC and lockout code inside WordPress, as data held in memory. Your host's firewall (Imunify360, ModSecurity, LiteSpeed), your CDN and other security plugins never see a test, so they have no reason to briefly ban the server's own address, and nobody receives "brute-force attack detected" emails.
* The brute-force check no longer sends failed logins. It first confirms that SecureLite's lockout is attached at every point of the login, then trips the real lockout from a reserved test address, and deletes its own counters before the step ends. If a step dies halfway (a host time limit), what it created is removed the next time the simulation runs or the Verification screen opens.
* Test events no longer appear in the security log, on the dashboard or in the daily summary.
* The .git and readme.html checks read your disk first. If there is no .git folder, or readme.html is missing or does not reveal your version, the check passes without asking the server anything.
* If the site cannot reach itself over HTTP, the simulation still runs: only the checks that need the server's answer report that they could not be tested.
* New: if XML-RPC blocking or user-enumeration blocking is switched on while login protection is off, the check now says these run as part of login protection, instead of reporting a plain failure. It also reports when another plugin turns XML-RPC back on.
* The simulation only asks your server for its home page when a check actually needs the server's answer, so a re-test of the firewall or login checks makes no request at all.
* Locked out of a site on your own computer? The Support screen, Settings and FAQ now say that on localhost your address is ::1 or 127.0.0.1, not your internet address, so a trusted-IP line with only your public address does not match.
* A run no longer lifts lockouts on the server's own address or 127.0.0.1. Earlier versions did this to undo their own test logins; behind a misconfigured proxy that could have released a real attacker.

= 0.2.16 =
* After an Attack Simulation in which every attack was blocked, one quiet line asks whether you would leave a review on WordPress.org, with "Leave a review" and "Not now". Either answer hides it for good. It never appears after a run with failures, and never on a site where a Support contact (such as the agency that looks after it) is set.

= 0.2.15 =
* Fixed: in WordPress Playground, including the Live Preview on WordPress.org, Attack Simulation reported the brute-force check as failed. Playground signs in every request automatically, so the test's deliberately wrong logins were accepted. The test now opts out of that, and the check works there as it does on a real site.
* Attack Simulation: "Enable & re-test" now re-tests only the checks the change affects (for example the six firewall checks), in a few seconds, instead of running every attack again. The other results stay as they were, and re-tested rows are marked. When more than one protection can be turned on, an "Enable all & re-test" button does them together. "Run again" is still the full test.
* When Attack Simulation's live view cannot start because something answers in its place (a firewall or another security plugin blocking admin-ajax.php, a hosting time limit, a PHP error), it now says so, with the HTTP status and page title, instead of "Unexpected token '<'". A button runs the simulation without the live view, which does not need admin-ajax.php.
* The firewall checks now follow a redirect that keeps the test attack in the address (for example http to https, or another plugin's redirect) and judge where it lands, as a real attacker's request would. Previously such a redirect was reported as "Not blocked (HTTP 301)". A redirect that drops the attack is reported as "could not test", with where it went.
* The firewall checks in Attack Simulation now use a fresh test address on every run, so a page cache or CDN can no longer answer with a response stored on an earlier run (results that flipped between Passed and Failed).
* The uploads check no longer reports "your server ignores the rule" when it cannot actually tell. On LiteSpeed servers (Hostinger and many other hosts) a request for a missing file is answered by WordPress before the uploads rule is applied, so the check now says it could not confirm and explains a 30-second manual test.

= 0.2.14 =
* Two-factor setup shows a QR code: point your authenticator app at the screen instead of typing a 32-character key. The code is drawn by the plugin on your server; your key is never sent to an outside QR service. Typing the key by hand is still there under "Can't scan?", with a Copy button, plus a Copy setup link button for password managers.
* Recovery codes can be copied, downloaded as a .txt file or printed. The browser asks before you leave the page until you tick "I have saved these codes", and a notice at the top of your profile points to them.
* Security: an authenticator code now signs you in only once. Before, the same six digits could be used again for about a minute and a half.
* On the login page, after you enter your password, your username stays filled in on the code step. WordPress cleared it, so you had to type everything again.
* New FAQ: how to set up two-factor and how to get back in if you lose your phone.
* Where you are already looking at a problem — malware the scan found, or a check that needs a server change — one line now says where to get hands-on help. If you have set a Support contact (for example the agency that looks after the site), it names them instead. Nothing is sent anywhere; these are ordinary links.
* Readme: a Need help? section — free support on the forum, and where to get hands-on help.

= 0.2.13 =
* Settings > Notifications has a "Send test email" button, so you can confirm your site delivers SecureLite's email now instead of waiting for the first summary. If sending fails, it shows the mailer's error.
* The daily summary now separates what was stopped from what was only logged. Requests seen while the firewall or rate limiting is in Monitor mode are no longer reported under "no action is needed"; the email says they were not blocked and where to switch to Block.
* Fixed: in WordPress Playground (and setups that pass your login cookie to the site's own requests), Attack Simulation reported the firewall, user-enumeration and upload checks as failed, because each test arrived logged in as you and administrators are never filtered. Test requests are now always treated as an anonymous visitor. The bot and user-enumeration checks also work where requests go through a browser, which cannot send a custom User-Agent and follows redirects itself.
* Attack Simulation's uploads check now recognises a hosting firewall that refuses PHP in uploads with a code other than 403 (such as LiteSpeed's 444): a harmless control request in the same folder tells a real PHP block apart from the host briefly blocking the test.

= Earlier versions =

The full history from 0.1.0 to 0.2.12 is in `changelog.txt` in the plugin folder. 0.2.13 was the first version published on WordPress.org.

== Upgrade Notice ==

= 0.2.23 =
A simpler Settings page that says plainly if anything is below recommended, the uploads check no longer shows "Skipped" on LiteSpeed hosts, and IPv6 visitors are counted by network block so bots cannot dodge limits.

= 0.2.22 =
SecureLite now blocks from install: firewall and rate limiting switch to Block, and new comment spam protection and Smart protection stop bots without puzzles. XML-RPC protection no longer breaks Jetpack. Cloudflare is recognised automatically.

= 0.2.21 =
The uploads PHP check now gives a clear pass or fail on many more sites, and no longer stops at an http-to-https redirect. Nothing is written to your server.

= 0.2.20 =
Other plugins' promotions no longer appear inside SecureLite's dashboard. No change to how protection works.

= 0.2.19 =
Attack Simulation now proves real requests reach the protections it tests, names any CDN in front of your site, and says plainly what each report covers.

= 0.2.18 =
Name and description update only. No change to how the plugin works.

= 0.2.17 =
Attack Simulation sends no attacks and no logins over the network — safe on live sites, invisible to your host's firewall, and it leaves nothing behind.

= 0.2.16 =
A one-time, dismissible review request after a fully passed Attack Simulation.

= 0.2.15 =
Faster Enable & re-test, an Enable all button, and more reliable Attack Simulation results on cached, redirected and LiteSpeed sites and in WordPress Playground.

= 0.2.14 =
Two-factor setup by QR code, recovery codes you can download, and each authenticator code now works only once.

= 0.2.13 =
Adds a Send test email button and a clearer daily summary, and makes Attack Simulation reliable on hosting firewalls and in WordPress Playground.

= 0.2.12 =
SecureLite no longer edits .htaccess: the uploads protection shows the rule to add, and the simulation checks it is enforced.

= 0.2.11 =
The malware scan checks WordPress core against the official release; Attack Simulation no longer reports a host firewall's blocks as failures.

= 0.2.10 =
Security: wp-config.php is no longer copied anywhere, and copies left by earlier versions are removed.

= 0.2.8 =
Security fixes: a locked-out address could still sign in, and forged proxy headers could bypass lockouts. Adds a Cloudflare preset, one-click wp-config.php escape hatch, and stops the firewall refusing editors' posts. Requires WordPress 6.2.

= 0.2.7 =
Fixes a lockout that a stranger could trigger against your own account, and makes the plugin remove its own server-level changes when you deactivate or uninstall it. Recommended for all users.

= 0.2.6 =
The system report now shows the live state of the login lockout and every plugin involved in your login, so "it isn't locking me out" is a question the screen answers rather than one you have to ask.

= 0.2.5 =
Settings switches are now toggles, and the file editor setting no longer shows a control that another plugin has already overridden.

= 0.2.4 =
Adds email notifications: a daily summary and two immediate alerts, sent by your own site. Designed so it cannot become the flood of mail that makes people switch security alerts off.

= 0.2.3 =
Two-factor now has recovery codes and refuses to switch on until you have proved your app works. Changing your login URL is tested before it is kept. Both close the ways a security plugin most often locks people out of their own sites.

= 0.2.2 =
Security fix: removes readable wp-config.php backups left in the site root by earlier versions. Also fixes a two-factor lockout and stops verified search engines being rate limited. Update as soon as you can.

= 0.2.1 =
Fixes a rate-limiter bypass in which a forged cookie name was accepted as proof of login. Adds a trusted-IP allowlist and a wp-config recovery constant. Recommended for all users.
