=== Witen Blocker ===
Contributors: witenlabs
Tags: security, firewall, blocklist, brute-force, spam
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 0.6.46
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Block abusive traffic, protect logins, and check suspicious files. Works locally or with Witen threat intelligence.

== Description ==

Witen Blocker provides local login protection, bot controls, and file checks without an account. Connect to Witen for shared threat intelligence.

* Limit login failures and enable two-factor authentication.
* Manage blocked IPs, trusted addresses, and individual bot policies.
* Check core files against WordPress.org checksums and monitor content changes.
* Scan files with bundled checks and connected detection catalogs.
* Review activity and reporting status.

Local features have no paid unlock or trial expiry. Hosted plans determine remote feeds, refresh frequency, and off-site backup storage. Scan findings need review; they do not prove that a file is malicious.

On shared hosting, enrolled sites check requests against local blocklists and return HTTP 403 for matches. Background jobs refresh intelligence and send reports. On managed servers, the optional Witen Warden agent can enforce blocks at the host firewall; WordPress retains its settings and bot policies.

Connecting authorizes security-event sharing. Read the service and privacy disclosures below. Unconnected sites keep events local.

== Installation ==

1. Upload the ZIP through **Plugins > Add New Plugin > Upload Plugin** and activate it.
2. Open **Witen > Settings** to configure local protection.
3. For hosted intelligence, create a [Witen account](https://witenlabs.com), add a WordPress site under **Protected Assets**, and save its one-time setup token in Witen settings after reviewing the service terms and privacy policy.
4. Let background maintenance connect, then check connection and blocklist status. Review trusted addresses and bot policies.

Alternatively, set `WITEN_ENROLLMENT_TOKEN` in `wp-config.php` and remove it after enrollment. `WITEN_COLLECTOR_URL` overrides the hosted collector if you operate another one.

**Connecting through Warden**

Set `WITEN_SOCKET_PATH` in `wp-config.php` and grant the PHP user socket access. This explicitly authorizes event sharing with Warden, which controls onward delivery. Automatic socket detection no longer enables sharing.

For Warden 0.1.18 and later, register the site's reporting ID and PHP Unix user with `warden callers add`. Store its credential outside the web root, owned by the PHP user with mode 0600:

    define( 'WITEN_SOCKET_PATH', '/run/witen/warden-ingest.sock' );
    define( 'WITEN_WARDEN_CREDENTIAL_FILE', '/private/path/warden-caller.token' );

Register credentials before upgrading Warden and check connection status. Multisite uses `WITEN_WARDEN_CREDENTIAL_FILES` to map blog IDs to separate files; unlisted blogs inherit no credential. Untrusted installations need separate Unix users for security isolation.

== Frequently Asked Questions ==

= Do I need an account or my own server? =

Local login, two-factor, comment, bot, file-integrity, and bundled malware checks, plus the .htaccess editor, need no account. Hosted intelligence needs outbound HTTPS. Warden requires server administration access.

= What happens during a service outage? =

Cached intelligence remains usable until expiry. Reports queue for background retries within the limits below. Socket mode does not fall back to a direct collector connection.

= Will it slow down my site? =

Checks use local data; synchronization and scans run in the background. The plugin still adds work to requests. Traffic-driven WordPress cron can delay jobs on quiet sites. Warden can block traffic before PHP runs.

= What about legitimate bots? =

Known Bots uses User-Agent and IP information. Choose individual bots to allow or block, or allowlist trusted IPs.

= Does it support multisite? =

Each site has separate settings, connections, logs, and jobs, initialized on its first request after network activation. The main site's network administrator manages shared .htaccess. Accounts and two-factor enrollment are network-wide. Deactivation clears jobs and preserves settings.

= How do updates work? =

After publication, WordPress.org handles updates. Settings and credentials are preserved; each site applies database and scheduling changes when the plugin next loads.

== External Services ==

**Witen Collector** — `https://collector.witenlabs.com`, or your configured collector.

Enrollment exchanges a setup token and installation identity for a credential. Background requests send events and inventory and retrieve blocklists, bot identities, signed malware catalogs, service availability, network statistics, Tor exit nodes, account allowlists, and threat-feed profiles. Profile changes send the selection and sensor identity. Manual IP lookups send the queried address for network/ASN information. Decision receipts send the IP, matched rule or policy, outcome, request context, and sensor identity. Event fields, retention, and consent are detailed below.

Malware samples are off by default. `WITEN_SEND_MALWARE_SAMPLES` set to boolean `true` in `wp-config.php` permits bounded file-content uploads. Scanning does not require them.

Off-site .htaccess backups are off by default. Enabling them permits uploads and background restores requested in the customer dashboard. Files are encrypted to the collector's public key, with checksum and size sent alongside. Witen can decrypt them for restores and keeps 10 versions. Restores validate downloaded content, create a local backup, and report results. Disabling backups stops uploads and remote restores; local editing and backups remain available.

[Witen terms](https://witenlabs.com/terms) | [Witen privacy policy](https://witenlabs.com/privacy). Other collector operators set their own policies. In socket mode, these events go to local Warden; its configuration determines onward transmission.

**Cloudflare IP Lists** — `https://www.cloudflare.com/ips-v4/` and `https://www.cloudflare.com/ips-v6/`.

Enrolled installations refresh proxy ranges during background maintenance to interpret forwarded client addresses safely. Offline installations use bundled ranges. Requests contain ordinary HTTPS network metadata, with no WordPress visitor events or account data. [Cloudflare terms](https://www.cloudflare.com/website-terms/) | [Cloudflare privacy policy](https://www.cloudflare.com/privacypolicy/).

**WordPress.org Core Checksums** — `https://api.wordpress.org/core/checksums/1.0/`.

Integrity scans request official core hashes using the installed WordPress version and locale, plus ordinary HTTPS network metadata. No visitor events, account data, or site content is sent. [WordPress.org privacy policy](https://wordpress.org/about/privacy/).

The plugin does not remotely load executable code or frontend assets. `includes/bot-identities.json` is local CC0-1.0 crawler data with adjacent license and provenance files. Website links and hostname patterns do not trigger requests or live crawler DNS checks. The configured DNS resolver receives collector hostname queries and the server address. Background jobs and Apache rule checks call the site's own WordPress URLs.

`includes/malware-catalog-public-key.txt` holds the public Ed25519 verification key; the private key is not shipped. Failed catalog updates retain the last verified copy.

== Privacy Policy ==

Events are shared only after enrollment or explicit `WITEN_SOCKET_PATH` configuration. Earlier events stay local and are never queued or uploaded retroactively. Connected threat intelligence requires sharing; use offline mode or deactivate the plugin to stop it.

**Data sent**

Security observations can include IP addresses; login failures and successes; XML-RPC calls; comment, registration, and 404 events; request URIs, methods, User-Agent strings, referrers, and query information; and attempted usernames, which may be email addresses. Installation inventory includes site name and URL, WordPress/PHP/plugin versions, and a random UUIDv7 identifier. An observed IP is not necessarily an attacker. The collector uses these reports to identify distributed attacks, correlate repeated failed logins with later successful ones, and maintain shared blocklists.

Event reports exclude form bodies, post content, comment text, password fields, cookies, and session data. URLs and metadata can contain personal data; keep secrets out of URLs and logs. Separately enabled samples contain file content; off-site backups contain .htaccess content.

**Retention and removal**

Collector retention and deletion follow that operator's published policy. Locally, the delivery queue holds at most 500 events for seven days. The plugin also keeps the latest 100 dashboard events and blocks, block and allow lists, and health counters. Rejected events and decision receipts are stored for diagnosis, limited to 100 records or 1 MiB per queue, with older records removed at the limit. These diagnostic records remain until replaced or uninstalled.

Uninstall removes Witen options, transients, scheduled actions, and database tables. Request collector-side deletion from its operator. `WITEN_NO_TELEMETRY` stops daily inventory reporting, but not connected security-event sharing.

== Changelog ==

= 0.6.46 =
* Clarify setup instructions, service disclosures, and the plugin directory description.

See `changelog.txt` in the download for older releases.

== Upgrade Notice ==

= 0.6.46 =
Updates the documentation. For Warden 0.1.18 or later, register a separate caller credential for each site before upgrading.
