=== IronGuardWP ===
Contributors: ironguardwp
Tags: security, malware, firewall, malware scanner, login security
Requires at least: 6.0
Tested up to: 6.8
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

All-in-one WordPress security: malware scanning, firewall, and login protection. Pure PHP, so it runs on any host.

== Description ==

IronGuardWP protects WordPress sites from malware, brute-force attacks, and known vulnerabilities. It scans your files against a curated malware definition set, blocks malicious traffic before it reaches WordPress, and tells you in plain language what happened and what to do about it.

**It runs anywhere.** The scanning engine is pure PHP. No ClamAV, no YARA, no SSH, no command line, no server access. If WordPress runs, IronGuardWP runs.

**Curated definitions, not a firehose.** Every signature is normalised into our own format, de-duplicated, and false-positive tested against a clean WordPress corpus before it reaches your site. Fewer false alarms on legitimate plugin code.

**Plain-language findings.** Every result says what happened, why it matters, and the recommended next step. No raw rule IDs as the headline, no unexplained jargon.

= What each plan includes =

Free, for one personal site:

* **Signature malware scan** — checks your files against known malware signatures and flags anything that matches.
* **Core integrity check** — compares WordPress core files against the official versions to spot tampering.
* **Login limiting** — locks out an attacker after repeated failed logins so brute-force attacks fail.
* **Security score** — a single score with a prioritised list of what to fix first.
* **Basic hardening** — one-click fixes for the common WordPress mistakes attackers rely on.

Plus adds:

* **Full / deep scan** — scans themes, plugins, and uploads, not just core files.
* **Real-time monitoring** — watches for file changes as they happen instead of waiting for the next scan.
* **Web application firewall** — blocks malicious requests before WordPress ever runs them.
* **IP allow / block and auto-blocking** — manual lists plus automatic blocking of attacking addresses.
* **Two-factor authentication** — a second step at login so a stolen password is not enough.
* **Security headers** — adds the HTTP headers that defend against clickjacking and content injection.

Pro adds:

* **Virtual patching** — shields a known plugin vulnerability at the firewall until the author ships a fix.
* **Shared threat feed** — addresses attacking one IronGuardWP site are blocked across the whole network.
* **Geo-blocking** — blocks traffic from countries you do not do business with.
* **Compromised password check** — warns when a user's password appears in a known breach.
* **Vulnerability alerts** — tells you when a plugin or theme you run has a newly disclosed CVE.
* **Auto-remediation** — cleans or repairs infected files automatically, with a restore point first.
* **Multi-site management** — all your sites and their security status in one dashboard.
* **Scheduled reports** — emailed security summaries, useful for client reporting.

Definition updates reach Free weekly, Plus daily, and Pro in real time.

= Design principles =

**It fails open.** If something in IronGuardWP goes wrong, it stops protecting rather than stopping your site. A failing component switches itself off and tells you, instead of throwing an error on every page. There is a documented emergency-disable procedure below, and lockouts always lift by themselves.

**Every destructive action is reversible.** Quarantine, repair, and delete all save a restorable copy first. If the copy cannot be saved, the action does not happen. Everything is restorable from the Quarantine screen with one click.

**It is built for shared hosting.** Scans run in small batches, pause when the server is busy, respect your `memory_limit` and `max_execution_time`, skip oversized files, and resume across requests. A scan that is interrupted picks up where it left off.

= Licensing =

One licence covers one site, meaning one domain. `www.example.com` and `example.com` are the same site. Separate domains need separate licences. Each licence also allows a small number of development environments, which the licence server identifies from your domain — there is no setting for it, and the plugin never claims to be a staging site on its own.

Billing, renewals, and cancellation happen through Whop. If you cancel, your licence runs to the end of the paid term and then the plugin drops back to Free. Nothing breaks and your site is never locked.

== Installation ==

1. Upload the `ironguardwp` folder to `/wp-content/plugins/`, or install the ZIP through Plugins, Add New, Upload Plugin.
2. Activate IronGuardWP through the Plugins screen.
3. Go to **IronGuardWP, Licence** and enter your licence key.
4. Go to **IronGuardWP, Scan** and run your first scan.
5. Work through the "What to fix first" list on the dashboard.

No Composer, no build step, and no command line are required. The plugin is a plain drop-in.

**Optional, recommended:** on the Firewall screen, turn on *early loading*. This installs a small must-use plugin so the firewall runs before themes and other plugins load, which catches attacks aimed at other plugins before that plugin's own code runs. It can be turned off again from the same screen, and it is removed automatically when you deactivate IronGuardWP.

== Frequently Asked Questions ==

= Will this slow my site down? =

Scans are incremental and throttled, and pause under load. The firewall adds a small amount of work per request. IronGuardWP is built for shared hosting — staying inside your host's CPU and memory limits is a design requirement, not an afterthought.

= Do I need server access or special software? =

No. The scanning engine is pure PHP. No ClamAV, no YARA, no SSH, no command line.

= What counts as one site? =

One domain. `www.example.com` and `example.com` count as the same site. Separate domains need separate licences.

= What happens if I cancel? =

Your licence runs to the end of the paid term, then the plugin drops back to Free. Nothing breaks and your site is never locked.

= Can a plugin like this lock me out of my own site? =

IronGuardWP is designed to fail open. Login lockouts are always time-limited and lift by themselves; an allow-listed address is never locked out; two-factor is only switched on for an account after that account has proved a working code. And there is an emergency-disable procedure below that works entirely over FTP, without the dashboard.

= You found malware — what now? =

Every finding tells you what was found, why it matters, and the recommended action. Quarantining a file saves a restorable copy first, so if a finding turns out to be a false positive you can put the file back with one click from the Quarantine screen.

= What happens if the licence server is unreachable? =

Nothing changes. Your features stay exactly as they are, and the plugin retries with a backoff. A network problem, a server outage, or a bad response never reduces what you have paid for. If our server stays unreachable for more than two weeks, the plugin verifies your licence directly with Whop instead — and even then it can only confirm what you already had, never less.

= What does the plugin send back to IronGuardWP? =

A daily check-in with counts, rule names, and the addresses that attacked your site. It never sends your content, file contents, usernames, email addresses, or your visitors' addresses. The Settings screen shows you the exact data that would be sent, and you can switch check-ins off entirely.

= Does country blocking work on my host? =

Only if your site is behind a CDN or proxy that tells us the visitor's country, such as Cloudflare. IronGuardWP does not bundle an IP-to-country database — that would mean shipping a large binary file or looking up every visitor with a third party. The Settings screen tells you plainly whether it can work on your server.

== Emergency disable ==

**If IronGuardWP is causing a problem, use one of these. Both work without dashboard access.**

= 1. The constant (recommended) =

Edit `wp-config.php` and add this line **above** the `/* That's all, stop editing! */` comment:

`define( 'IRONGUARDWP_DISABLE', true );`

The plugin stops loading immediately. WordPress carries on completely normally, the plugin stays "active" on the Plugins screen but does nothing, and no settings or data are lost. Remove the line to switch it back on.

To disable **only the firewall** while leaving scanning and the dashboard working:

`define( 'IRONGUARDWP_DISABLE_FIREWALL', true );`

To disable **only two-factor authentication** — for example if someone has lost their authenticator app and their recovery codes:

`define( 'IRONGUARDWP_DISABLE_2FA', true );`

= 2. Rename the folder =

Over FTP, SFTP, or your host's file manager, rename:

`wp-content/plugins/ironguardwp`

to anything else, for example `ironguardwp-off`.

WordPress deactivates a plugin whose main file has disappeared, so the plugin is switched off on the next page load. The must-use firewall loader, if you installed it, detects the missing folder and turns itself into a no-op rather than causing an error.

To restore, rename the folder back and reactivate the plugin from the Plugins screen.

= 3. If you installed early loading =

Early loading adds one file:

`wp-content/mu-plugins/ironguardwp-firewall.php`

Deleting that file is safe and removes early loading. Nothing else depends on it. It is also removed automatically when you deactivate IronGuardWP.

= Locked out of wp-admin? =

Login lockouts are stored as WordPress transients and always expire on their own — the default is 20 minutes. Waiting is enough. If you cannot wait, use the constant in step 1: it clears the lockout check along with everything else.

== Screenshots ==

1. The dashboard: security score, outstanding findings, and a prioritised list of what to fix first.
2. Findings, each in plain language: what happened, why it matters, and what to do.
3. The scan screen, showing incremental progress and the installed definition set.
4. The firewall log and IP allow / block lists.
5. Quarantine, where every action taken on a file can be undone.

== Upgrade Notice ==

= 1.0.0 =
First release.

== Changelog ==

= 1.0.0 =
* First release.
* Pure-PHP signature scanning engine with regex, hash, and substring signature types, run under strict PCRE backtracking limits so a bad pattern can never take a site down.
* Hash signatures support sha256 and md5, and refuse degenerate digests so one bad definition cannot flag every empty file on a site.
* Incremental definition updates, applied only on top of the exact version they were built against.
* WordPress core file integrity checking against the official checksums API.
* Incremental, throttled, resumable scanning that respects shared-host memory and execution limits.
* Web application firewall with an optional must-use early-load path, plus virtual patching on Pro.
* Login limiting, two-factor authentication, IP allow / block lists with automatic blocking, geo-blocking, and the compromised-password check.
* Security score with one-click hardening fixes.
* Reversible quarantine, repair, and delete, each with a restore point.
* Licence client with HMAC-verified, replay-protected entitlements that never downgrade a site because of a network failure.
