=== Guardian Web ===
Contributors: sergiogongil
Tags: firewall, security, anti-bot, anti-scanner, karma
Requires at least: 5.6
Tested up to: 6.9
Requires PHP: 7.4
Stable tag: 1.1.3
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Lightweight PHP firewall. Blocks bots, scanners and known-bad IPs before WordPress loads. Powered by the Guardian Web Karma Network.

== Description ==

Guardian Web is a lightweight security plugin for WordPress. Instead of running as a regular plugin — which means it loads *after* WordPress has already bootstrapped — it installs a small "shield" as a must-use plugin (mu-plugin). That way the shield runs **before** WordPress, and blocks known-bad traffic before any database query or theme code is executed.

**Features**

* Block IPs with a history of abuse using the collaborative Karma Network.
* Detect vulnerability scanners and automated bots.
* Honeypot detection: identify bots that follow hidden links.
* Optional country-based blocking (configured from the panel).
* Remote maintenance mode.
* External panel with statistics, logs and configuration.
* Dashboard widget showing visits, attacks, blocked requests and top countries.

**Why the shield lives in mu-plugins**

WordPress runs plugins only after the core has loaded and the database is reachable. If your goal is to block obviously hostile traffic, that's already too late — you've paid the CPU cost. Must-use plugins load first, which is why Guardian Web installs its shield there. The plugin you install from the WordPress directory is a thin controller: it writes the shield into `wp-content/mu-plugins/` **only when you click Activate**, and removes it cleanly when you deactivate or uninstall.

You need write permission on `wp-content/mu-plugins/` for this to work. That directory is writable by default on most shared hosts.

**Free account required**

The analysis engine and the Karma database live on `app.guardianweb.es` — the plugin doesn't run analysis locally, it asks the panel. This means you need a free account at [guardianweb.es](https://guardianweb.es/) to use the plugin. The free tier is fully functional: firewall, Karma network and dashboard widget are included at no cost. Paid plans exist for users who want extra sites, long-term log retention and advanced features, but none of those are required to use the plugin.

== External services ==

This plugin connects to `app.guardianweb.es`, a hosted service operated by Guardian Web. Connecting to the service is the core of what the plugin does; it does **not** work offline.

**When it connects**

* When you save your API key in Settings → Guardian Web (one-time verification request).
* Every few minutes, to refresh the list of blocked IPs and configuration.
* When loading the WordPress dashboard (to fetch statistics for the widget, cached for 5 minutes).
* On every visit to your site the shield may ask the panel whether the visitor's IP is in the Karma network (this request does not include any user content — only the visitor IP and your site's API key).

**What is sent**

* Your site's API key (64-hex, generated by the panel when you register your site there).
* The visitor's IP address, user agent and requested URL path — used only to decide whether to block the request.
* Your site's hostname.

**What is NOT sent**

* No form content, no POST bodies, no cookies, no user accounts, no post content, no database dumps.

**Terms and Privacy**

* Terms: [https://guardianweb.es/en/terminos](https://guardianweb.es/en/terminos)
* Privacy: [https://guardianweb.es/en/privacidad](https://guardianweb.es/en/privacidad)

By installing and activating this plugin you acknowledge that the above data will be sent to `app.guardianweb.es`. The plugin will prompt you for explicit consent the first time you save an API key.

== Installation ==

1. Install the plugin from the WordPress plugin directory, or upload the ZIP from `Plugins → Add New → Upload Plugin`.
2. Activate **Guardian Web** from the plugins list.
3. Go to **Settings → Guardian Web**.
4. If you don't have an account, register for free at [guardianweb.es](https://guardianweb.es/) and add your site.
5. Copy the API key from the panel and paste it into the plugin settings.
6. The first time you save, you'll be asked to tick the *I accept the privacy notice* checkbox to allow the plugin to contact `app.guardianweb.es`. Tick it, leave *Activate protection now* checked (it is checked by default), and click **Save**. The shield is installed into `wp-content/mu-plugins/` and protection becomes active immediately. Without both checkboxes the plugin will not write anything outside its own folder.

You can toggle protection on/off at any time from the same settings page. Deactivating the plugin or unticking the activation also removes the shield files.

== Frequently Asked Questions ==

= Is it free? =

Yes. The free plan at guardianweb.es includes the firewall, the Karma Network and the dashboard widget. Paid plans exist with more sites per account and advanced reports, but the plugin works 100% with the free plan.

= Does it slow my site down? =

No. The shield keeps a local cache of banned IPs and only contacts the panel when the cache expires (every 5 minutes by default). Added latency per request is typically under 1 ms.

= What happens if guardianweb.es is unreachable? =

The shield fails open: if it can't reach the panel, it lets traffic through normally. Your site never goes down because of the firewall.

= Can I disable protection temporarily? =

Yes, from the same settings page. Disabling removes the mu-plugin immediately. Your API key is kept so you can re-enable with one click.

= Why does the plugin install a file in mu-plugins/? =

Must-use plugins load before any regular plugin and before WordPress routing kicks in, which is the earliest point at which we can block hostile traffic. The file written is small (a loader + the shield), signed with your API key, and removed cleanly on uninstall.

= Is my data shared with other sites? =

The Karma Network shares *aggregate* attack signals — namely, which IPs have attacked which sites. It does not share your site's content, your users' data or your logs. See the privacy link above for full details.

= I changed my site's domain. Do I need to reinstall? =

Just save the settings again. The shield re-writes itself with the current hostname on every save.

== Screenshots ==

1. Settings page: paste your API key and activate the shield in one click.
2. Dashboard widget: visits, attacks and blocked requests in the last 24 hours, plus top countries.
3. External panel: full dashboard with logs, statistics, country blocking and configuration.
4. Country blocking: toggle protection per country from the panel.
5. Plugin list: quick link to settings from the standard WordPress plugin row.

== Changelog ==

= 1.1.3 =
* Full refactor to comply with WordPress.org plugin guidelines.
* All HTTP calls now use the WordPress HTTP API (`wp_remote_get` / `wp_remote_post`) instead of cURL.
* Cache files moved from the plugin directory to `wp-content/uploads/guardian-web/` so the plugin no longer writes inside its own folder.
* In-memory caches (Karma, GeoIP) migrated to the WordPress Transients API.
* Footer markup (CAPTCHA / honeypot) now injected via `wp_footer` actions instead of `ob_start` output buffering.
* All user input from `$_SERVER` is sanitized (`sanitize_text_field`, `esc_url_raw`, `wp_unslash`).
* Internal logging removed; only fatal errors go to the standard PHP `error_log`.
* All function, class, constant, option and hook names prefixed with `guarwe_` / `Guarwe_` / `GUARWE_` to avoid collisions, per the WP.org reviewer feedback.
* Direct-access guard (`ABSPATH`) added to every PHP file.

= 1.1.2 =
* Plugin Check fixes for the WordPress.org directory automated review.
* `Tested up to` bumped to WordPress 6.9.
* Readme title aligned with the plugin header (`Guardian Web`); the longer tagline is kept as the short description.
* Settings UI: the "activate now" checkbox is now labelled "Activar protección ahora" to match the privacy documentation.
* Installation step explicitly documents the privacy consent checkbox and the activation toggle.

= 1.1.1 =
* WordPress.org directory release. No functional changes over 1.1.0.
* Privacy notice before the first API-key submission (required by WordPress directory guidelines).
* README rewritten to document the external service (`app.guardianweb.es`) explicitly.
* Tested up to WordPress 6.7.

= 1.1.0 =
* Dashboard widget now shows real stats: visits, attacks and blocked requests in the last 24 hours, plus top countries and attack types in the last 7 days.
* Transient cache (5 minutes) to avoid hammering the panel.
* Minor cleanup in the settings screen.

= 1.0.0 =
* First release: API-key connection, enable/disable from the WordPress admin, dashboard widget.

== Upgrade Notice ==

= 1.1.3 =
Full refactor required by the WordPress.org review team: WP HTTP API, Transients, sanitization, and `guarwe_` prefixes everywhere. Strongly recommended.

= 1.1.2 =
Cosmetic and documentation fixes required by the WordPress.org automated review. No functional changes; safe to update.

= 1.1.1 =
Required for submission to the WordPress plugin directory. Adds an explicit consent step before sending data to the external panel. No action required by existing users.

= 1.1.0 =
Adds real stats to the dashboard widget. Requires the `wp-stats.php` endpoint on the panel (shipped with the matching server release).

= 1.0.0 =
Initial release.
